偶尔我会遇到这样的问题,即我想表达“请将最后一个参数重复使用”,例如为了以 pointfree 的风格编写代码或者避免使用 lambda 表达式。例如:
sqr x = x * x
可以写成:
sqr = doubleArgs (*) where
doubleArgs f x = f x x
或者考虑这个稍微复杂一点的函数(摘自这个问题):
ins x xs = zipWith (\ a b -> a ++ (x:b)) (inits xs) (tails xs)
如果有这样的一个函数,我可以写出这段代码的pointfree形式:
ins x = dup (zipWith (\ a b -> a ++ (x:b))) inits tails where
dup f f1 f2 x = f (f1 x) (f2 x)
但是因为我在Hoogle中找不到类似doubleArgs或dup的东西,所以我猜我可能错过了一些技巧或成语。
pointfree
,dup
可以转换为liftM2
。我真的需要更好地掌握函数的单子实例。 - Antal Spector-Zabuskysqr = (*) <$> id <*> id
,它也可以工作 :-) - Landeiconcat [a,[x],b]
而不是a ++ [x] ++ b
。 - Landeifmap
和return
与环境无关,正如你所期望的那样,等等。我最喜欢的用法之一是使用条件组合器(<?>)
,可以像这样使用even <?> (\
div` 2) <*> (+ 1),我认为这比
\n -> if even n then ndiv
2 else n + 1更易读。(注意——
liftM2 (\b t e -> if b then t else e)将从两个分支产生副作用,但这与
Reader` 无关) - C. A. McCannjoin
函数的作用。谢谢。 - N3dst4