GHC 7.0.3 は利用できませんが、これで動作するはずです。
次のように手動で辞書を渡すことができます (例としてContext
=を使用):Show
{-# LANGUAGE ScopedTypeVariables, TypeFamilies, ExistentialQuantification #-}
data ShowDict a = Show a => ShowDict
class Class a where
data Associated a :: * -> *
getShow :: ShowDict (Associated a b)
-- Convenience function
getShowFor :: Class a => Associated a b -> ShowDict (Associated a b)
getShowFor _ = getShow
showAssociated :: Class a => Associated a b -> String
showAssociated a =
case getShowFor a of
ShowDict -> -- Show (Associated a b) is made available by this pattern match
show a
instance Class Int where
data Associated Int b = Foo deriving Show
getShow = ShowDict
main = print $ showAssociated Foo
これは、提案する関数のコピーに多少似ていますが、利点は次のとおりです。
- (`Context` のメソッド シグネチャの) 繰り返しを避ける
- `Show Baz` をコンテキストに持つことは、`Show Baz` を必要とする (ライブラリ) 関数を呼び出したり、`Show [Baz] のような暗黙のインスタンスを使用したりできるため、単に `Baz` を表示するための関数を持つよりもいくらか強力です。 `:
showAssociateds :: forall a b. Class a => [Associated a b] -> String
showAssociateds as =
case getShow :: ShowDict (Associated a b) of
ShowDict ->
show as
主な欠点は、使用にgetShow
は常に明示的な型シグネチャが必要であることです ( のような関数getShowFor
はこれを軽減できます)。