functionhaskelltypespolymorphismpolymorphic-functions

Polymorphic types in Haskell


I came across this function

iter p f x = if (p x) then x else (iter p f (f x))

and I thought I'd give a go at defining the polymorphic types myself to understand the concept.

My thought was the following:

The function takes 3 parameters, so we have t1 -> t2 -> t3 -> T

  1. p is being used inside the if condition so it must return a bool, therefore t1 = a -> Bool

  2. f is also the same type as p because it is passed as an argument in the else block, therefore t2 = a -> Bool

  3. x is being used inside the if condition so it must return a bool, therefore t1 = a -> Bool

But when i checked the type in the ghci, the type they gave me was

iter :: (t -> Bool) -> (t -> t) -> t -> t

Can someone please explain the reasoning behind this.

Thanks


Solution

  • The function takes 3 parameters, so we have t1 -> t2 -> t3 -> T

    This is correct as a starting point.

    p is being used inside the if condition so it must return a bool, therefore t1 = a -> Bool

    Correct.

    f is also the same type as p because it is passed as an argument in the else block, therefore t2 = a -> Bool

    Incorrect. f is never used in the same way as p. In the else block f is being applied to x and the result passed as the last argument to iter. From that we know f x must be the same type as x so f :: a -> a.

    x is being used inside the if condition so it must return a bool, therefore t1 = a -> Bool

    Incorrect. In the if condition x is being used only as an argument to p. You established above p :: a -> Bool. Therefore x :: a.

    But when i checked the type in the ghci, the type they gave me was

    iter :: (t -> Bool) -> (t -> t) -> t -> t

    Correct. You could also write this replacing t with a to be consistent in the notation - we used a above:

    iter :: (a -> Bool) -> (a -> a) -> a -> a