You have three answers right now, but maybe not much understanding.
The problem is that you have two x on the right side, and it doesn't seem like there is a good way to remove them. To "duplicate" you need a function with one of the following signatures: x:
x -> (x, x) x -> (x -> a, x -> b) -> (a, b) ((x, x) -> y) x -> y (x -> x -> y) -> x -> y (x -> y) -> (x -> y -> z) -> (x -> z)
It is actually surprisingly hard to find; I would suggest that the first one would be available under the name dup x = (x, x) , but it could not be found anywhere. As far as I know, not one of them is found anywhere in the prelude.
It turns out that there the Monad is called the "Reader" monad, which imposes a single value (in this case, your x ) on many functions. This type of monad is (->) x , which means that for all y these are functions x -> y . The second-last function above (x -> x -> y) -> x -> y can simply be written as:
Prelude> :m + Control.Monad Prelude Control.Monad> :t (id >>=) (id >>=) :: (a -> a -> b) -> a -> b
Therefore, you can write simply:
id >>= (==) . reverse
or even more briefly:
palindrome = reverse >>= (==)
It turns out that all other versions secretly use (>>=) behind the scenes. It turns out, for example, that each Monad is Applicative , and the Control.Applicative library exports the symbol (<*>) :: Applicative f => f (x -> y) -> fx -> fy . In the case of f being (->) a , we have: (<*>) :: (a -> x -> y) -> (a -> x) -> y , which we can apply to (==) and reverse to get:
palindrome = (==) <*> reverse
Or Control.Monad has the same instance Monad ((->) x) and exports for it as >>= (as indicated above, (x -> y) -> (y -> x -> z) -> x -> z and join :: m (mx) -> mx , which in this case (x -> x -> y) -> x -> y .
There are many options, but the declaration of these instances is done in these libraries. If you want to do this without these libraries, you will have to write a tedious version:
instance Monad ((->) x) where return = const yx >>= zxy = \x -> zxy (yx x) x
before applying these features. At this point, it is almost easier to write:
Prelude> let dup x = (x, x) Prelude> let palindrome = uncurry ((==) . reverse) . dup Prelude> :t palindrome palindrome :: Eq a => [a] -> Bool