Haskell:递归数据类型(参数化类型)

时间:2018-10-26 01:36:51

标签: haskell

我有这个:

data Val s i a = S s | I i | A a deriving (Show)

与Haskell中的非均匀列表一起玩。所以我可以做类似的事情(只是一个示例函数):

oneDown :: Val String Int [String]-> Either String String

但是我实际上希望这是Val的列表,例如:

oneDown :: Val String Int [Val]-> Either String String

1 个答案:

答案 0 :(得分:2)

您要查找的内容将导致无限数据类型,Haskell明确禁止使用该数据类型。但是,我们可以将此无限量隐藏在新类型后面,并且编译器不会抱怨。

data Val s i a = S s | I i | A a deriving (Show)
newtype Val' = Val' (Val String Int [Val']) deriving (Show)

它仍然完全按照您的示例做(加上一些类型构造函数,这些构造函数将在运行时进行优化),但是现在我们可以无限递归了,因为我们已经保护了递归类型。 >

这实际上是recursion-schemes库为获取归纳定义的数据所做的操作,我们可以在该数据上定义通用递归技术。如果您对像这样的通用数据类型感兴趣,可以看看该库。

要构造这种新型类型,我们必须使用Val'构造函数。

let myVal = A [Val' (I 3), Val' (S "ABC"), Val' (A [])]