来自First Principles的Haskell练习说要实现filter
使用foldr
,这就是我想出的,但它感觉和看起来很笨重.是否有更自然的方式来实现它foldr
?
import Data.Bool
myFilter :: (a -> Bool) -> [a] -> [a]
myFilter f = foldr (\x -> bool (++ []) ((:) x) (f x)) []
Run Code Online (Sandbox Code Playgroud)
我只会通过使用谓词bool
组成一个调用来简单地让我摆脱lambda表达式:.但是,并不是唯一需要在list元素上调用的函数; 也一样.你可以使用实例来编写函数bool
p
bool iffalse iftrue . p
p
(:)
Applicative
myfilter p = foldr (bool id . (:) <*> p) [] -- yuck
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,我只会if
在lambda表达式中使用一个普通的表达式:
myfilter p = foldr (\x -> if p x then (x:) else id) [] -- much clearer!
Run Code Online (Sandbox Code Playgroud)
注意,当专用于函数时,Applicative
's (<*>)
运算符被定义为f <*> g = \x -> f x (g x)
.我将它留作练习使用该定义转换bool id . (:) <*> p
成
\x -> bool id (x:) (p x)
.