【问题标题】:Haskell data variableHaskell 数据变量
【发布时间】:2015-01-13 16:25:07
【问题描述】:

我有一个简单的列表结构,其中每个叶子都包含两个值(a 和 b),每个节点都包含一个值(a)

data List a b = Leaf (a, b) | Node (a, (List a b)) deriving Show

我有这个函数只是返回一个节点的值或叶子的第一个值

func (Leaf (a, b)) = a
func (Node (a, c)) = a

有没有办法避免这些模式匹配之一?事实上,我正在研究具有多个参数的三叉树和函数,所以我有很多模式匹配,它们都在做同样的事情。

我想过这样的事情

func (var (a, b)) = a

其中 var 可以是叶子或节点,但这不起作用。

【问题讨论】:

  • (a, b) 实际上可以被认为是一个值。答案是,我认为,no,或者至少 no,除非你可以使用 SYB。
  • 作为一个附带问题,您的语法比您需要的要多。你可以做等效的结构List a b = Leaf a b | Node a (List a b),然后将这两个模式定义为top (Leaf a _) = atop (Node a _) = a
  • “变量”这个词在 Haskell-Land 中是一个诅咒词。这个词是datatype,而不是'datavariable'。

标签: list variables haskell tree


【解决方案1】:

如果您对它感到满意,您可以将您的类型重构为:

data List a b = L (a, Either b (List a b)) deriving Show

那么,

func :: List a b -> a
func (L (a,_)) = a

以前的值,如

Leaf (a, b)
Node (a, list)

现在写成

L (a, Left b)
L (a, Right list)

根据您的代码,这可能更方便使用。

但是,请记住,如果您需要访问该对的第二个组件,则无论如何都需要进行模式匹配。总体而言,您当前的数据类型可能比此替代方案更方便。

【讨论】:

    【解决方案2】:

    我通过添加一个返回第一个值的帮助函数来“解决”它

    gf (Leaf (a, b)) = a
    gf (Node (a, b)) = a
    

    所以我可以一直使用这个功能

    func x = gf x
    

    仍然有两个模式匹配,但在更复杂的函数需要多个参数的情况下,避免大量模式匹配很有用

    addValues (Leaf (a, b)) (Leaf (c, d)) (Leaf (e, f)) = a + c + e 
    addValues (Leaf (a, b)) (Leaf (c, d)) (Node (e, f)) = a + c + e 
    addValues (Leaf (a, b)) (Node (c, d)) (Leaf (e, f)) = a + c + e 
    addValues (Leaf (a, b)) (Node (c, d)) (Node (e, f)) = a + c + e 
    addValues (Node (a, b)) (Leaf (c, d)) (Leaf (e, f)) = a + c + e 
    addValues (Node (a, b)) (Leaf (c, d)) (Node (e, f)) = a + c + e 
    addValues (Node (a, b)) (Node (c, d)) (Leaf (e, f)) = a + c + e 
    addValues (Node (a, b)) (Node (c, d)) (Node (e, f)) = a + c + e
    

    现在可以写成

    addValues (a, b, c) = (gf a) + (gf b) + (gf c)
    

    【讨论】:

      猜你喜欢
      • 2017-04-15
      • 2011-01-10
      • 2010-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多