Your function o
is very similar to function composition .
:
(.) :: (b -> c) -> (a -> b) -> a -> c
f . g = \x -> f (g x)
you could rewrite the definition of .
and just slightly rearrange the arguments:
o :: a -> (a -> b) -> (b -> c) -> c
o x f g = g (f x)
or you could try to create o
by shuffling around the arguments of .
:
o = (flip .) . flip . (flip .) $ (.)
In this definition, we are using flip
to swap the first and second argument of (.)
and (flip .)
to swap the second and third argument. For a function a -> b -> c -> d
that would give us:
a -> b -> c -> d
-- swap b and c with (flip .)
a -> c -> b -> ->d
-- swap a and c with (.)
c -> a -> b -> -> d
-- swap a and b
c -> b -> a -> d with (flip .)
If you're wondering why (flip .)
swaps the second and third argument, I recommend you read this answer and the blog post that was linked in it. it boils down to .
making sure that flip
gets applied to the result of whatever function you pass to (flip .)
and swapping the first and second argument of the result of a function is the same as swapping its second and third argument.
To be perfectly honest though, I don't see the need for your o
function since you could just rewrite f
as:
f :: Int -> String
f x = g . h $ x
or even
f = g . h