我想使用列表理解仅打印 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]
但这不起作用。为什么?
我想使用列表理解仅打印 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]
但这不起作用。为什么?
你真的应该考虑使用filter
,像这样:
filter isTrue [1,2,3,4,5,6,7]
[f(x)|x<-list,x==True]
这表示“给我一个f x
1的列表,其中x
来自list
并且x
等于True
。
但是对于您的情况,您已list
作为数字列表传递。看起来您只想包含那些f x
返回的数字True
。因此,与其比较x
和True
发射f x
,你应该做相反的事情。更像是:
[x | x <- list, f x == True]
但我们可以进一步改进这一点。==
是一个函数,它接受两个参数,True
如果它们相等则返回,如果不相等则返回False
。所以f x == True
将返回True
if f x
isTrue
和False
if f x
is 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
在函数之后简单地写出参数(必要时用空格分隔)。括号仅用于控制优先级和形成元组。如果您开始尝试通过在参数列表周围放置括号来调用多个参数的函数,那么您将遇到更多错误。
中listTo
,list
有类型[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]
。
我并不完全清楚这段代码应该做什么,但你应该考虑使用map
or filter
。