如何在Haskell中使用具有数据类型的高阶函数

时间:2016-01-29 00:21:37

标签: haskell algebraic-data-types

考虑以下数据类型。

data Movement = Credit Float | Debit Float
    deriving Show

现在这个功能。

retrieveBiggerThan :: [Movement] -> Float -> [Movement]
retrieveBiggerThan l k = (filter (\(Credit c) -> c>k) l) ++ (filter (\(Debit c) -> c>k) l)

如果我测试这个,我会收到“lambda中非穷举模式”的输出:

retrieveBiggerThan [Credit 5.5, Debit 2.3, Credit 3.3] 2

[Credito 5.5*** Exception: ficha7.hs:116:35-53: Non-exhaustive patterns in lambda

我相信这是因为过滤器只期望data Movement中定义的构造函数之一。有没有机会做这样的事情(一个过滤器能够在检查列表的同时考虑两个构造函数)?

filter (\((Credit c) || (Debit c)) -> c > k) listofmovements

3 个答案:

答案 0 :(得分:5)

您可以使用LambdaCase扩展名使lambda更简洁:

topic.subscribe

答案 1 :(得分:5)

在这种特定情况下,您可以使用记录语法。

data Movement = Credit { value :: Float } | Debit { value :: Float }
retrieve l k = filter (\mvmt -> value mvmt > k) l

答案 2 :(得分:2)

你可以创建一个名为absMovement的助手,然后使用它来简单地filter

absMovement :: Movement -> Float
absMovement (Credit c) = c
absMovement (Debit  d) = d

retrieveBiggerThan k =
  filter (\x -> absMovement x > k)

(注意函数的curried定义及其参数顺序翻转 - 由于许多实际原因,这在Haskell中更为惯用,超出了本文的范围)

如果您愿意,也可以点免费(r):

retrieveBiggerThan k =
  filter $ (k <) . absMovement

其中显示:&#34;检索大于k [运动]相当于过滤[运动],其运动更强大于k&#34; - 括号内的短语对应于参数他们被困扰了#34;

P.S。完全错过了实际使用记录语法,你可以免费获得absMovement函数,正如Daniel Wagner指出的那样;但在我看来,再次把它想象成abs很好。