我没有可用的 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` 比仅具有显示 `Baz` 的函数更强大,因为它允许您调用需要 `Show Baz` 的(库)函数,或使用隐含的实例,如 `Show [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
可以缓解这种情况)。