4

我想使用列表理解仅打印 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]

但这不起作用。为什么?

4

3 回答 3

5

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

filter isTrue [1,2,3,4,5,6,7]
于 2013-04-24T14:16:51.533 回答
5
[f(x)|x<-list,x==True]

这表示“给我一个f x1的列表,其中x来自list并且x等于True

但是对于您的情况,您已list作为数字列表传递。看起来您只想包含那些f x返回的数字True。因此,与其比较xTrue发射f x,你应该做相反的事情。更像是:

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

但我们可以进一步改进这一点。==是一个函数,它接受两个参数,True如果它们相等则返回,如果不相等则返回False。所以f x == True将返回Trueif f xisTrueFalseif f xis 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在函数之后简单地写出参数(必要时用空格分隔)。括号用于控制优先级和形成元组。如果您开始尝试通过在参数列表周围放置括号来调用多个参数的函数,那么您将遇到更多错误。

于 2013-04-25T00:28:44.873 回答
2

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

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

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

于 2013-04-24T14:16:44.420 回答