2013-04-24 181 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]