自动推断多参数实例



接下来,我有以下类型类:

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的确切实例。我错过了什么?

您可以这样做:

class SafeCopy a m where
  putSafe :: a -> m
instance BuilderS m String => SafeCopy Person m where
  putSafe p = cstr "name" (name p)

你需要打开很多语言扩展。

相关内容

  • 没有找到相关文章

最新更新