Haskell - How to write (.) f f = (\\x -> f (f x))

笑着哭i 提交于 2019-12-06 10:45:32
Will Ness

In Haskell, arguments to a function must have unique names. Using the same name for another argument is not allowed. This is because

foo x y = ...    ===    foo = (\x-> (\y-> ...))

and if y where replaced with x, the second x would just shadow the first inside the ... body: there would be no way to reference the first x from there.

You can just define twice f x = f (f x):

Prelude> :t twice
twice :: (t -> t) -> t -> t
Prelude> twice (+1) 4
6


Alternatively, f (f x) = (.) f f x = join (.) f x:

Prelude Control.Monad> :t join (.)
join (.) :: (b -> b) -> b -> b

join is defined in Control.Monad. For functions, it holds that join g x = g x x. It is also known as W combinator.

E.g. print $ join (.) (+1) 4 prints 6.

As the error message says, you have conflicting definitions for f in the definition (.) f f = (\x -> f (f x)). You are binding the name f to both the first and second arguments to (.), so ghci doesn't know which argument to use when evaluating the expression f x.

There is nothing wrong with defining (.) using the pattern (.) f g, and then calling it with two arguments that happen to be the same.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!