簡體   English   中英

Haskell 檢查列表是否為奇數

[英]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 xx > 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM