[英]Haskell check if list is odd
我需要檢查一個列表是否只包含大於 10 的奇數。這就是我所做的。
f :: [Int] -> Bool
f xs= [x |x<-xs, x >10, odd x]
為什么它不起作用? 謝謝
當你寫[x |x<-xs, x >10, odd x]
你正在組成一個Int
的列表,一個[Int]
,而不是一個Bool
。 例如,您可以驗證[x | x <- [1..20], x > 10, odd x]
[x | x <- [1..20], x > 10, odd x]
是列表[11,13,15,17,19]
。 所以它確實包含你想要的數字,但是你怎么知道這些是xs
中的所有數字?
您當然可以將該列表等同於xs
本身,這將起作用:
f xs = xs == [x |x<-xs, x >10, odd x]
這樣==
確保當你只從xs
取大於 10 的奇數時,你會得到准確的xs
,這意味着所有數字都滿足謂詞。
也許這就是你要找的錯誤。
我不確定這個解決方案是否遍歷xs
兩次(一次提取滿足謂詞的條目,一次檢查相等性)。 看起來很簡單,所以我不禁想到這個列表只遍歷了一次。
無論如何,另一種策略是堅持您的要求:您希望列表xs
all
odd x
和x > 10
都為True
數字x
:
f :: [Int] -> Bool
f xs = all (\x -> odd x && x > 10) xs
通過注意到雙方都有一個尾隨xs
,你可以減少定義:
f :: [Int] -> Bool
f = all (\x -> odd x && x > 10)
如果你願意,這個 lambda 可以更簡潔地定義為(odd & (> 10))
,從而得到
f :: [Int] -> Bool
f = all (odd & (> 10))
如果您import Control.Monad (liftM2)
並定義
(&) :: (a -> Bool) -> (a -> Bool) -> (a -> Bool)
(&) = liftM2 (&&)
您的類型簽名提到該函數返回一個布爾值,但您建議的主體返回一個數字列表。 Haskell 沒有像 Lisp 那樣的自動轉換。
如果你想堅持行人代碼,你可以獲得違規號碼的子列表,只需檢查子列表是否為空。
f :: [Int] -> Bool
f xs = let offenders = [x | x <- xs, x <= 10 || even x]
in (null offenders)
如果你想要一些更像 Haskell 的東西,你可以使用sequence :: (Traversable t, Monad m) => t (ma) -> m (ta)
多態庫函數將謂詞列表轉換為單個函數返回一個布爾值列表,然后將該列表傳遞給and
。 那檢查一個數字。
然后使用all
將這些檢查應用於輸入列表中的所有數字。 像這樣:
f2 :: [Int] -> Bool
f2 = all (and . sequence [(>10), odd])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.