我试过这个例子 http://www.haskell.org/haskellwiki/GHC.Generics#A_generic_function
即:
import GHC.Generics
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DefaultSignaturesGeneric #-}
data Bin = O | I deriving Show
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf deriving Generic
class GSerialize f where
gput :: f a -> [Bin]
instance GSerialize U1 where
gput U1 = []
instance (GSerialize a, GSerialize b) => GSerialize (a :*: b) where
gput (x :*: y) = gput x ++ gput y
instance (GSerialize a, GSerialize b) => GSerialize (a :+: b) where
gput (L1 x) = O : gput x
gput (R1 x) = I : gput x
instance (GSerialize a) => GSerialize (M1 i c a) where
gput (M1 x) = gput x
instance (Serialize a) => GSerialize (K1 i a) where
gput (K1 x) = put x
class Serialize a where
put :: a -> [Bin]
default put :: (Generic a, GSerialize (Rep a)) => a -> [Bin]
put = gput . from
instance Serialize Int
instance Serialize Char
instance Serialize Bool
instance (Serialize a) => Serialize (UserTree a)
toserialize :: (Serialize (UserTree a) ) => UserTree a -> [Bin]
toserialize tree = put tree
我通过调用测试了该函数:
toserialize Leaf
这里编译器给出了错误消息:
Ambiguous type variable `a0' in the constraint:
(Serialize a0) arising from a use of `toserialize'
Probable fix: add a type signature that fixes these type variable(s)
In the expression: serialize Leaf
In an equation for `it': it = toserialize Leaf
这里缺少什么?
答案 0 :(得分:2)
问题是因为a
中的类型变量UserTree a
在Leaf
构造函数中根本没有出现,所以GHC无法确定您想要的a
值。您可以通过添加显式类型签名(例如
toserialize (Leaf :: UserTree Int)
更新:示例toserialize (Node 2 Leaf Leaf)
挂起,因为Int
的通用表示是递归的
type Rep Int = D1 D_Int (C1 C_Int (S1 NoSelector (Rec0 Int)))
对于没有“普通”构造函数的“原始”类型,通常需要手动定义实例。但是,因为例如Bool
只是
data Bool = True | False
这适用于通用Serialize
实例
toserialize (Node True Leaf Leaf)