Вы можете использовать синтаксис еще больше, чтобы помочь вашему пониманию:
filter' :: (a -> Bool) -> [a] -> [a]
filter' p [] = []
filter' p (x:xs)
| (p x) == True = x : ( filter' p xs )
| otherwise = ( filter' p xs )
То есть
filter' :: (a -> Bool) -> [a] -> [a]
filter' p [] = []
filter' p (x:xs)
| (p x) = x : ( filter' p xs )
| otherwise = ( filter' p xs )
Или перевести его на более простые конструкции,
filter' :: (a -> Bool)
-> [a] -> [a]
filter' p = ( \ xs -> case xs of
{ [] -> []
; (x:ys) | p x -> x : ( filter' p ys )
; (x:ys) -> ( filter' p ys ) } )
"p
" для "предиката" .Он используется filter'
для проверки каждого x
на входе xs
, чтобы решить, включать ли этот x
или нет в выходной файл, в соответствии со значением Bool
ean, которое произвело тестирование.
p
просто передается без изменений от одного вызова filter'
к следующему.Это обычно закодировано с помощью так называемого преобразования «рабочий-обертка»,
filter' :: (a -> Bool) -> [a] -> [a]
filter' p xs = go xs where
go [] = []
go (x:xs) | p x = x : go xs
| otherwise = go xs
Наконец, более простое определение может также быть
filter' :: (a -> Bool) -> [a] -> [a]
filter' p xs = go xs where
go [] = []
go (x:xs) = [x | p x] ++ go xs
, которое хорошо соответствует *Определение на основе 1030 *
filter' p = foldMap (\ x -> [x | p x])