Write Yourself a Scheme in 48 Hoursを読んでいる。5章の評価2の最後あたり。
Schemeにはゆるく等価性を評価するequal?ってやつ。
(eqv? 2 "2") #f (equal? 2 "2") #t
これを実装するために異る型のリストを作りmapMで順番に評価していく
data Unpacker = forall a. Eq a => AnyUnpacker (LispVal -> ThrowsError a) unpackEquals :: LispVal -> LispVal -> Unpacker -> ThrowsError Bool unpackEquals arg1 arg2 (AnyUnpacker unpacker) = do unpacked1 <- unpacker arg1 unpacked2 <- unpacker arg2 return $ unpacked1 == unpacked2 `catchError` (const $ return False) -- or :: [Bool] -> Bool equal :: [LispVal] -> ThrowsError LispVal equal [arg1, arg2] = do primitiveEquals <- liftM or $ mapM (unpackEquals arg1 arg2) [AnyUnpacker unpackNum, AnyUnpacker unpackStr, AnyUnpacker unpackBool] eqvEquals <- eqv [arg1, arg2] return $ Bool $ (primitiveEquals || let (Bool x) = eqvEquals in x) equal badArgList = throwError $ NumArgs 2 badArgList
よろしくやってくれるデータ型を定義すればいいらしい。
ちょっとよくわからなかったので、適当な例をつくってみることにした。
{-# LANGUAGE ExistentialQuantification #-} data HeteroEq = forall a. Eq a => HeteroEq (a -> Bool) heterolist = [HeteroEq (3==), HeteroEq ("test"==), HeteroEq (True==)]
でもちょっとよくわからん。
追記 120701
これを読めばいいのかな