Haskell中的多个类型列表

时间:2012-10-12 19:14:09

标签: generics haskell types functional-programming polymorphism

说我有一组记录,如

data A = A { a:: String } deriving (Show)
data B = B { b:: String } deriving (Show)

然后是一些类型

class Foo a where
    foo :: a -> IO ()

instance Foo A where
    foo c = ...

我也想做类似

的事情
bar = do
    push (A {a="x"})
    push (B {b="y"})

让这些东西最终放在某个地方,以便稍后运行,这样我就可以

map foo l

我应该编写模板haskell来生成包装器类型并派生实例,以便列表可以是包装器类型吗?有更聪明的方法来解决这个问题吗?我老实说感觉受到了haskell类型系统的影响,并且知道必须有更好的方法来做到这一点。

2 个答案:

答案 0 :(得分:15)

有一些方法可以通过存在量化来做到这一点,但它通常是矫枉过正的。更多Haskell-y方法是简单地预先应用foo并保留[IO ()]生成的操作列表,然后您可以sequence运行它们。

答案 1 :(得分:2)

使用Existential的一个例子,但我真的不愿意使用它,并建议hammar告诉你。

{-# LANGUAGE ExistentialQuantification #-}
data A = A String deriving Show
data B = B String deriving Show

class Foo a where
    foo :: a -> IO ()

instance Foo A where
    foo c = putStrLn $ "FOOA " ++ show c

instance Foo B where
    foo c = putStrLn $ "FOOB " ++ show c

data Wrap = forall a . Foo a => Wrap a

instance Foo Wrap where
    foo (Wrap c) = foo c

bar :: [Wrap]
bar = [Wrap $ A "x", Wrap $ B "y"]

main = mapM_ foo bar