Paa*_*yim 7 haskell types function
我有两个haskell函数,它们在两个代数数据类型之间进行转换.
data Ab = A | B
data Cd = C | D
fromAb :: Ab -> Cd
fromAb A = C
fromAb B = D
toAb :: Cd -> Ab
toAb C = A
toAb D = B
但我想创建一个多态函数,它采用代数数据类型并在它们之间进行转换.
foo A = C
foo B = D
foo C = A
foo D = B
但是Haskell从"foo A = C"推断出函数是
foo :: Ab -> Cd
我试图使类的数据类型实例使foo变形,但它不起作用.
class Abcd a
instance Abcd Ab
instance Abcd Cd
foo :: Abcd a => a -> Ab
有任何想法吗?
jbe*_*man 14
这很自然TypeFamilies.您定义了一个类型级函数
type family Converted a
type instance Converted Ab = Cd
type instance Converted Cd = Ab
然后你的签名变成了
foo :: a -> Converted a
如果你只是在摆弄你要完成的类型,但由于你想在价值层面上有不同的行为(A从a C等返回),我们实际上需要在新类型的实例之间传播我们的案例:
class Convertable a where
    foo :: a -> Converted a
instance Convertable Ab where
    foo A = C
    foo B = D
instance Convertable Cd where
    foo C = A
    foo D = B
(现场演示)
最后,Converted如果使用最近的GHC ,您可以考虑创建一个封闭类型的同义词系列,或者通过移动Convertable实例声明中的实例使其"关联" .