跟进this,我有以下类型类:
class Monoid m => BuilderS m a where
cstr :: String -> a -> m
class SafeCopy a where
putSafe :: a -> m
为BuilderS
提供实例:
import qualified Data.Serialize.Builder as B
instance Serialize a => BuilderS B.Builder a where
cstr _ = B.fromByteString . encode
instance BuilderS CustomBuilder Int where
cstr = ...
instance BuilderS CustomBuilder String where
cstr = ...
etc.
我想像这样定义SafeCopy
的实例:
data Person = Person { name :: String, age :: Int }
instance SafeCopy Person where
putSafe p = cstr "name" (name p)
但是,在这种特定情况下,编译器无法找到BuilderS m String
的实例。我尝试了几件事:
putSafe
的约束中:
putSafe :: (BuilderS m Int, BuilderS m String, ...) => a -> m
。这是可行的,但不可扩展(即如果我希望将来有BuilderS m Vector
约束怎么办?)m
添加到SafeCopy
。data SumT m = forall a b. (BuilderS m a, BuilderS m b) => a :+: b
,然后使用putSafe :: a -> SumT m
。但是,我没有向类型系统提供足够的信息,因此它可以推迟决定使用BuilderS
的确切实例以供日后使用。我错过了什么?
答案 0 :(得分:1)
您可以这样做:
class SafeCopy a m where
putSafe :: a -> m
instance BuilderS m String => SafeCopy Person m where
putSafe p = cstr "name" (name p)
您需要启用大量语言扩展程序。