【问题标题】:Using condition in list comprehension in haskell在haskell的列表理解中使用条件
【发布时间】:2013-04-24 14:10:49
【问题描述】:

我想使用列表推导来只打印 true

listTo::(a->b)->[a]->[b]
listTo f list=[f(x)|x<-list,x==True]

isTrue::Int->Bool
isTrue n
    |n>=5 =True
    |n<5 =False


listTo isTrue[1,2,3,4,5,6,7]

但这不起作用。为什么会这样?

【问题讨论】:

  • 您将 x(a 型)与 True(Bool)进行比较
  • 为了将来参考,当“这不起作用”得到更多详细信息时,问题会更容易回答。它是否无法编译(如果是,错误信息是什么)?它会产生错误的结果吗?如果确实有效,您希望得到什么结果?

标签: haskell list-comprehension higher-order-functions


【解决方案1】:
[f(x)|x<-list,x==True]

这说“给我一个f x的列表1,其中x来自listx等于True

但对于您的情况,您已将 list 作为数字列表传递。看起来您只想包含f x 返回True 的那些数字。因此,与其将xTrue 进行比较并发出f x,不如反其道而行之。更像是:

[x | x <- list, f x == True]

但我们可以进一步改进这一点。 == 是一个函数,它接受两个参数,如果相等则返回 True,如果不相等则返回 False。所以如果f xTruef x == True 将返回True,如果f xFalse,则False。似乎是白费力气;你可以写f x

[x | x <- list, f x]

这就是你如何使用列表推导来做到这一点。但正如邮递员所指出的,已经有一个标准库函数可以做到这一点:filter。如果您编写代码是为了完成工作,而不是学习事物的工作原理,那么这就是您将使用的方法。


1 请注意,f(x) 仅被解析为 f,应用于括号内的子表达式 (x)。在x 周围加上括号没有任何作用,所以这完全等同于f x。 Haskell 的函数应用语法不是类似于 C 的function(arg1, arg2, arg3),而是function arg1 arg2,其中参数只是在函数之后写出(必要时用空格分隔)。括号用于控制优先级和形成元组。如果您开始尝试通过在参数列表周围加上括号来调用多个参数的函数,那么您将遇到更多错误。

【讨论】:

    【解决方案2】:

    你真的应该考虑使用filter,像这样:

    filter isTrue [1,2,3,4,5,6,7]
    

    【讨论】:

      【解决方案3】:

      listTo 中,list 的类型为 [a]。因此x 的类型为a。但是你在比较 x == True,这意味着 x 应该有类型 Bool - 矛盾。

      如果您将类型签名更改为listTo :: (Bool -&gt; b) -&gt; [Bool] -&gt; [b],它将编译。但是,您将无法将它与listTo isTrue [1,2,3,4,5,6,7] 一起使用,因为[1,2,3,4,5,6,7] 显然不是[Bool] 类型。

      我并不完全清楚这段代码应该做什么,但您应该考虑使用 mapfilter

      【讨论】:

        猜你喜欢
        • 2021-06-15
        • 1970-01-01
        • 1970-01-01
        • 2017-10-14
        • 1970-01-01
        • 2018-06-07
        • 1970-01-01
        • 1970-01-01
        • 2022-01-08
        相关资源
        最近更新 更多