问题描述
我有两个haskell函数,它们可以在两种代数数据类型之间进行转换。
data Ab = A | B
data Cd = C | D
from Ab :: Ab - >来自Ab的Cd
来自Ab的= B
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
实例Abcd Ab
实例Abcd Cd
foo :: Abcd a => a - > Ab
任何想法?
这很自然, TypeFamilies
。您定义了一个类型级别的函数
type family转换一个
类型的实例Converted Ab = Cd
type实例转换Cd = Ab
然后您的签名变成
foo :: a - >转换了
如果你只是在摆弄你要做的类型,但因为你想拥有在价值层面上的不同行为(从 C
等等返回一个 A
)我们实际需要分摊我们的情况跨越新类型的实例:
class Convertable a where
foo :: a - >转换
实例可转换ab其中
foo A = C
foo B = D
实例可转换Cd其中
foo C = A
foo D = B
()
最后,您可以考虑制作 Converted
如果使用最近的GHC,则使用封闭类型同义词族,或者通过移动 Convertable
实例声明中的实例使其关联。
I have two haskell functions, which convert between two algebraic data types.
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
But I would like to make a polymorph function, that takes both algebraic data types and converts between them.
foo A = C
foo B = D
foo C = A
foo D = B
But Haskell deduces from "foo A = C" that the function is
foo :: Ab -> Cd
I tried to make the data types instances of a class to make foo polymorph but it didn't work.
class Abcd a
instance Abcd Ab
instance Abcd Cd
foo :: Abcd a => a -> Ab
Any Ideas?
This is very natural with TypeFamilies
. You define a type-level function
type family Converted a
type instance Converted Ab = Cd
type instance Converted Cd = Ab
Then your signature becomes
foo :: a -> Converted a
If you just were fiddling with types you'd be done, but since you want to have different behavior on the value level (returning an A
from a C
and so on) we actually need to spread our cases across instances of a new type class:
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
Finally, you might consider making Converted
a closed type synonym family if using recent GHC, or make it "associated" by moving the instances inside the Convertable
instance declarations.
这篇关于Haskell多态函数在代数数据类型之间进行转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!