【问题标题】:Is it possible to make a recursive datatype in haskell that accepts more than one specific type?是否可以在 haskell 中创建一个接受多个特定类型的递归数据类型?
【发布时间】:2013-07-26 19:44:52
【问题描述】:

例如,我想创建一个允许灵活嵌套的列表类型,如下所示:

[[['a'],'a'],'a']

可以在haskell中实现吗?我将如何编写它的类型签名?任何帮助都会很棒!!!

【问题讨论】:

    标签: list haskell types type-parameter recursive-datastructures


    【解决方案1】:

    这与其说是一个列表,不如说是一棵树。因此,您可以使用树数据类型来表示它。一个例子是the rose tree in containers,它的定义大概是:

    data Tree a = Node a [Tree a]
    

    但在这种情况下,可能更合适的树类型是这样的(顺便说一下,[]free monad;玫瑰树是 cofree comonad):

    data Tree a = Leaf a | Node [Tree a]
    

    使用这种类型,您可以像这样表示您的“列表”,例如:

    Node [Node [Node [Leaf 'a'], Leaf 'a'], Leaf 'a']
    

    【讨论】:

    • Hmmm.... 是否可以结合 Lists 和 Tree 的定义来使 Tree 成为 Monoid(这样mempty 将是 List 的 Empty)?
    • 我不认为我跟随。如果您希望获得上面编写的语法,那是不可能的。如果您想为Tree 创建一个Monoid 实例,您可能会想出一些东西,但我不确定它与您的问题有什么关系。如果您希望 []Tree 是同一类型,那是不可能的。这里没有任何名称为Empty 的东西。所以我不明白你的意思。
    • 对不起,我的意思是 Empty 作为 LYAH 书中解释的 List 数据类型的值构造函数(其中 : 被替换为 Cons)。无论如何,我认为你是对的,肯定有办法让Tree 成为Monoid 的实例,但是有很多不同的方法,不值得问哈哈。例如,当为两棵树定义mappend 时,它们如何相加?第二棵树是否成为第一棵树的最低子节点的子节点,或者它们是否在层次结构的每个级别上混合在一起。不过感谢您的反馈!
    【解决方案2】:

    您需要使用不同的值构造函数定义自己的数据类型。

    来自ghci

    Prelude> data Val a = Val a | List [Val a] deriving (Show)
    Prelude> [List [List [Val 'a']], Val 'a']
    [List [List [Val 'a']],Val 'a']
    

    及其类型:

    Prelude> :t [List [List [Val 'a']], Val 'a']
    [List [List [Val 'a']], Val 'a'] :: [Val Char]
    

    另外,查看 JSON 在 Real World Haskell 中的表示方式:http://book.realworldhaskell.org/read/writing-a-library-working-with-json-data.html (搜索data JValue查找相关数据类型)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-26
      相关资源
      最近更新 更多