我想实现一个带有从给定T类型转换的函数conv的类。 伪代码(不编译)看起来像这样:
data T a b c d = List [a] | Tup1 a | Tup2 a b | Tup3 a b c deriving (Show)
class ConvT t where
conv :: T a b c d -> t
instance ConvT [a] where
conv (List x) = x
instance ConvT (a,b) where
conv (Tup2 a b) = (a,b)
我该怎么做? 请注意,我不打算在生产中使用它 - 我只是对更了解Haskell类型系统感兴趣。
答案 0 :(得分:0)
您的类型类承诺,您可以将(T a b c d)
转换为t
,适用于任何类型a b c d t
。但是实例声明只有在类型之间存在某种对应关系时才有效。例如,List
大小写仅在t
为[a]
时有效,因此它不是您定义的类型类的有效实例。
我不是Haskell专家,但我认为这是不可能的,因为没有办法为conv
编写正确的类型签名。
答案 1 :(得分:0)
首先,请注意,这没有多大意义,因为您正在尝试定义一系列功能,每个功能都是继承的部分功能。它可以完成,它只需要扩展。
解决方案1:MPTC
class ConvT a b c d t where
conv :: T a b c d -> t
instance ConvT a b c d [a] where
conv (List x) = x
instance ConvT a b c d (a,b) where
conv (Tup2 a b) = (a,b)
解决方案2:约束种类和类型系列。
class ConvT t where
type ConvC t a b c d :: Constraint
conv :: ConvC t a b c d => T a b c d -> t
instance ConvT [a] where
type ConvC [a] a' b c d = a ~ a'
conv (List x) = x
instance ConvT (a,b) where
type ConvC (a,b) a' b' c d = (a ~ a', b ~ b')
conv (Tup2 a b) = (a,b)
注意:此代码未经过测试,但可以了解相关信息。另外,不要这样做。