How type declarations in brackets work in Haskell like (Integer -> Integer) -> Integer

Viewed 124

I am a beginner at Haskell and programming. I am learning how to write functions based on type declarations.How to write function which types are declared in brackets like (a -> b) -> b.

When I tried this:

z :: (Integer -> Integer) -> Integer
z x y = x + y

I got an error like this:

    • Couldn't match expected type ‘Integer’
                  with actual type ‘(Integer -> Integer) -> Integer -> Integer’
    • The equation(s) for ‘z’ have two arguments,
      but its type ‘(Integer -> Integer) -> Integer’ has only one

If I give only one parameter assigned to the integer, it does type check,

z f = 9

but no idea how to use that function as it show an error when i type z 9:

  • No instance for (Num (Integer -> Integer))
        arising from the literal ‘5’
        (maybe you haven't applied a function to enough arguments?)
    • In the first argument of ‘z’, namely ‘5’
      In the expression: z 5
      In an equation for ‘it’: it = z 5

How to write proper functions for such type declarations and how do they work?

1 Answers
z :: (a -> b) -> c

is the signature of a function that takes a a -> b and returns a c; and a -> b is in turn a function that takes a a and returns a b.

The definition

z x y = x + y

is incompatible with that type. This latter function, indeed, has signature

z :: Num a => a -> a -> a

which you can think of as the same as the following

z :: a -> b -> c

where the use of + in the definition has the effect of requiring that

  • a be a Num,
  • and b and c be the same as a.

When you write

z :: (Integer -> Integer) -> Integer
z f = 9

you are defining a function z which takes a function Integer -> Integer, doesn't use it at all, and returns 9 regardless.

So you could call z (+3), i.e. passing the function "plus 3" to z, and you would get out 9.

In fact, you'll get 9 whenever you feed z with something that can be seen as Integer -> Integer. This is obviously true for z (+3), z (subtract 9), and so on, but it's also true for z undefined, because undefined has type undefined :: a, i.e. it can take the place of any type, including Integer -> Integer.

Related