0

The function composition operator in Haskell is defined as:

(.) :: (b -> c) -> (a -> b) -> a -> c

When I try to create my own function composition operator, o in Haskell, it does not work, what am I doing wrong?

o :: a -> (a -> b) -> (b -> c) -> c

g :: Double -> String
g x = show x 

h :: Int -> Double
h x = fromIntegral x

f :: Int -> String
f x = o x h g       -- can it also be written like this: f = o h g 

Error message:

C:\Users\August\Desktop\Haskell\Template\Ex.hs:36:1: error:
    The type signature for `o' lacks an accompanying binding
Failed, modules loaded: none.
August Jelemson
  • 962
  • 1
  • 10
  • 29
  • 1
    It doesn’t work for exactly the reason the error message says: you wrote a type signature for `o` but didn’t write a definition such as `o x f g = g (f x)`. – Jon Purdy Jun 28 '17 at 22:15

1 Answers1

2

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
overactor
  • 1,759
  • 2
  • 15
  • 23