[英]Haskell: Is there a left-side identity for the infix (`:`) operator?
換句話說,在以下過濾器實現中,我可以使用什么語法(如果有的話)代替XXX
:
filter' :: (a -> Bool) -> [a] -> [a]
filter' _ [] = []
filter' f (x:xs) =
let n = if f x then x else XXX
in n:(filter' f xs)
我知道以下替代實現(它是遞歸的,只是prepends)但如果中綴運算符具有LHS身份,仍然會很奇怪。
filter' :: (a -> Bool) -> [a] -> [a]
filter' _ [] = []
filter' f (x:xs)
| f x = x:(filter' f xs)
| otherwise = filter' f xs
空無一人。 這可以看出因為
ghci> length (undefined : [])
1
所以不管你放在哪個元素,你總會得到1的長度。
這句話怎么樣:
filter' f (x:xs) =
let n = if f x then (x:) else id
in n (filter' f xs)
手波警報:以下嚴格來說是謊言(因為undefined
等),但它仍然是一個有用的想法。
使用Haskell data
聲明定義的類型的一個關鍵屬性是它們是空閑的 : data
類型的值集與該類型的正常形式術語集 (完全計算的表達式)是同構的。 如果該類型的兩個術語不同,則它們具有不同的值。
x : xs
, x : xs
和xs
(在同一范圍內)必須是不同的列表,因為它們是不同的術語。
換句話說, data
類型的語義是,如果在構造函數應用程序上進行模式匹配,則總是會返回相同的構造函數及其參數。 例如,無論x
和xs
是什么,這兩個表達式都保證為True
:
case [] of
[] -> True
x:xs -> False
case (x:xs) of
[] -> False
x':xs' -> x == x' && xs == xs'
您正在尋找的左側身份值將是此處第二個表達式的反例。 因此,沒有這樣的價值。
沒有,但++
確實有一個身份,即[]
。 所以這也會起作用:
filter' _ [] = []
filter' f (x:xs) =
let n = if f x then [x] else []
in n ++ (filter' f xs)
這與@ luqui的答案(正如你可以證明的那樣)效率相同,但效率卻低一些。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.