2013-04-24 182 views
2

列表理解使用情况我想用列表解析只打印真正在哈斯克尔

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] 

但是,这是行不通的。为什么?

+0

你在比较x(类型a)和真(Bool) – Arjan 2013-04-24 14:16:54

+0

为了将来的参考,当“这不起作用”的问题更详细时,问题更容易回答。它是否编译失败(如果是这样,错误信息是什么)?它会产生错误的结果吗?如果它确实有效,你期望得到什么结果? – Ben 2013-04-25 00:30:07

回答

2
[f(x)|x<-list,x==True] 

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

但是对于您的情况,您已通过list作为数字列表,而且看起来像您只想包括f x返回True的那些号码。因此,而不是比较xTrue并发出f x,你应该做相反的事情。更像是:

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

但我们可以进一步改善这一点。 ==是一个函数,它带有两个参数,如果相等则返回True,如果不相等则返回False。因此,如果f xTrueFalse,如果f xFalse,则f x == True将返回True。看起来像是浪费精力;你可以写f x

[x | x <- list, f x] 

所以这就是你如何使用列表理解来做到这一点。但是,正如邮递员所说,已经有一个标准的库函数来完成这个工作:filter。如果你正在编写代码来完成任务,而不是学习如何工作,那么这就是你会用到的。


注意f(x)只是解析为f施加到parenthesised子表达式(x)。将括号放在x附近什么也不做,所以完全等价于f x。 Haskell的函数应用语法是而不是 C-like function(arg1, arg2, arg3),而是function arg1 arg2,其中参数只是在函数后面写出来(如果需要,由空格分隔)。圆括号仅用于,用于控制优先级和形成元组。如果你开始试图通过在参数列表中放置圆括号来调用多个参数的函数,那么你将会遇到更多的错误。

2

listTolist[a]。因此x的型号为a。但是,那么你在比较x == True,这意味着x应该有Bool - 一个矛盾。

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

这并不完全清楚这个代码应该做什么,但你应该看看使用mapfilter

5

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

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