2

次のように、一連のレコードがあるとします。

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型システムにかなり固定されていると感じており、これを行うにはもっと良い方法が必要だと知っています。

4

2 に答える 2

15

存在量化でこれを行う方法はありますが、多くの場合やり過ぎです。より Haskell 的なアプローチは、単純に前もって適用し、結果のアクションのリストをfoo保持し、後でそれらを実行できるようにすることです。[IO ()]sequence

于 2012-10-12T19:20:23.200 に答える
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
于 2012-10-12T19:27:14.747 に答える