我不明白為什么map . filter泛型型別是map . filter :: (a -> Bool) -> [[a]] -> [[a]].
我知道地圖和過濾器型別是map :: (a -> b) -> [a] -> [b]和filter :: (a -> Bool) -> [a] -> [a]。還有(.) :: (b -> c) -> (a -> b) -> a -> c。
所以我的猜測是a = (a -> Bool) -> [a],b = [a]由于 filter 的輸出不是函式,我認為這map . filter會回傳一個期望函式的函式(a -> b)。
我不明白為什么型別是 的串列串列a,因為既沒有map也沒有filter串列串列。我也不明白為什么它只適用于一個功能,因為兩者都需要一個。
有人可以解釋一下它是如何作業的嗎?
uj5u.com熱心網友回復:
首先,讓我們為函式中的型別使用不同的字母。這樣我們就不會糊涂了。
map :: (a -> b) -> [a] -> [b]
filter :: (c -> Bool) -> [c] -> [c]
(.) :: (e -> f) -> (d -> e) -> d -> f
所以現在我們考慮map . filter. 進行替換,我們得到以下結果(~用于型別相等):
d ~ (c -> Bool)
e ~ ([c] -> [c]) -- Result of 'filter'
e ~ (a -> b) -- Argument of 'map'
f ~ ([a] -> [b])
請注意我們如何為e. 通過替換,
a ~ b ~ [c]
所以因此
f ~ ([[c]] -> [[c])
所以我們可以代替dandf在和的定義中(.)得到
(c -> Bool) -> [[c]] -> [[c]]
這就是 GHCi 告訴我們的。
這個函式實際上做的是將過濾器應用于每個子串列;所采用的函式引數map是過濾器。所以在 GHCi 中,
Prelude> import Data.Char
Prelude Data.Char> (map.filter) isDigit ["foo123", "456bar"]
["123","456"]
uj5u.com熱心網友回復:
的型別 (.),
(.) :: (b -> c) -> (a -> b) -> a -> c
-- f . g :: a -> c when g :: a->b, f :: b->c
意思是
g :: a -> b
f :: t -> c
-------------------- , b ~ t
f . g :: a -> c
然后按照同樣的模式,我們馬上得到
filter :: (a->Bool) -> ([a] -> [a])
map :: ( s -> t ) -> [ s ] -> [ t ]
-----------------------------------------------------------
s ~ [a] t ~ [a]
-----------------------------------------------------------
map . filter :: (a->Bool) -> [[a]] -> [[a]]
這也有道理。(map . filter) p = map (filter p),所以這map適用filter p于串列的每個元素(就像maps 一樣)。
既然p :: a -> Bool,那么filter p :: [a] -> [a]。
由于此函式應用于串列的每個元素,這意味著該串列的每個元素都具有 type [a],并轉換為另一個[a]。
因此整個串列是[[a]],轉換的結果也是[[a]]。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/350109.html
