【问题标题】:Haskell filter using fst and snd in query在查询中使用 fst 和 snd 的 Haskell 过滤器
【发布时间】:2020-10-25 20:03:43
【问题描述】:

我对haskell 很陌生,我正在尝试过滤第一个元素大于第二个元素的所有元组。我不明白为什么这不起作用,有什么帮助吗?

main = 
 do
  let xs = [2, 3, 2]
  let ys = [1, 2, 3]
  let cs = zip xs ys
  filter ((>snd).fst) cs

【问题讨论】:

  • "第一个元素大于第二个" — 你缺少比较函数 (>)
  • 请不要使用do 块。列表是Monad 的一个实例,但main 的类型为IO a,所以是另一个monad。
  • @LewisClark:这是行不通的,因为.fst 将提取元组的第一个元素,然后您打算将其与函数 snd 进行比较。但函数不是Ord 的实例,数字2 也不是函数。
  • @LEwisClarck:确实如此。在这种情况下,它是let ... in,所以是let xs = [2,3,2] in let ys = [1,2,3] in zip xs ys。这是do 块之外。
  • 请用完整的代码和错误信息发布正确的问题。

标签: haskell


【解决方案1】:

你可以过滤:

filter (\x -> fst x > snd x) cs

但您首先不需要使用fstsnd,您可以使用uncurry :: (a -> b -> c) -> (a, b) -> c

filter (<b>uncurry (&gt;)</b>) cs

uncurry 接受一个函数a -&gt; b -&gt; c,并将其重写为一个接受二元组(a, b) 的函数,从而调用包含在二元组中的元素的函数。

【讨论】:

  • 旁注:uncurry 在这里专门用于 2 元组;一种更灵活的编写方式,同时保持它的无点是使用 Applicative 实例来实现函数:(&gt;) &lt;$&gt; fst &lt;*&gt; snd;那么如果该对被替换为正确的数据类型,则可以将其更改为(&gt;) &lt;$&gt; someField &lt;*&gt; anotherField,而要保留uncurry,您需要先将类型映射为一对,例如uncurry (&gt;) . (someField &amp;&amp;&amp; anotherField).
猜你喜欢
  • 1970-01-01
  • 2019-11-05
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多