我想将我的类型类与类型相关联,该类型是某个类型类的实例(例如Show
)。
用肱二头肌解决方案
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
class (Show msg) => Handler msg h | h -> msg where
handle :: h -> msg -> String
因此,我可以实现Handler
,它仅处理关联类型的数据。
data IntHandler = IntHandler
instance Handler Int IntHandler where -- OK.
handle _ x = show x data Foo = Foo
handle IntHandler 1 -- OK.
handle IntHandler "1" -- Fail.
data Foo = Foo
data FooHandler = FooHandler
instance Handler Foo FooHandler where -- Fails to typecheck, Foo is not an instance of Show
handle _ _ = "failed"
问题:如何使用类型族实现相同的功能?
让我们尝试声明Handler'
类及其对IntHandler'
类型的实现:
{-# LANGUAGE TypeFamilies #-}
class Handler' h where
type Msg h
handle' :: h -> Msg h -> String
data IntHandler' = IntHandler'
instance Handler' IntHandler' where
type Msg IntHandler' = Int
handle' _ x = show x
好,此类型检查。现在让我们为Foo
类型创建实现:
data Foo = Foo
data FooHandler' = FooHandler'
instance Handler' FooHandler where
type Msg FooHanler' = Foo
handle' _ _ = "this won't fail"
但是它也可以进行类型检查,但是我想阻止它进行类型检查。那么,如何约束类型函数Msg
的结果?
答案 0 :(得分:2)
正如@Carl所指出的,这很明显:
false
这是我愚蠢的错误...只需启用class (Show (Msg h)) => Handler h where
。