5

Why does this identity compile when I type it

f = (\x -> x) :: a -> a

but this one does not?

f x = x :: a -> a

When I just write

f x = x

And load it into ghci and type :t f I receive

f :: p -> p

So, shouldn't it be the same thing?

The error I receive is

Couldn't match expected type ‘a1 -> a1’ with actual type ‘p’ because type variable ‘a1’ would escape its scope This (rigid, skolem) type variable is bound by an expression type signature: forall a1. a1 -> a1

I already googled about the rigid, skolem thing and the error but it only gave me more questions.

Originally I wanted to write a function that takes two inputs and returns the first one, which only worked with the anonymous function. So I seem to lack some understanding when it comes to lambdas and typing. I am still at the beginning of learning Haskell.

f = (\x y -> x) :: a -> b -> a
1
  • 3
    The type annotation only applies to the RHS of the definition, not the entire definition. Commented Dec 4, 2019 at 12:21

1 Answer 1

6

You apply the type signature :: a -> a to x, not to f. You can add a type signature with:

f :: a -> a; f x = x

However, you can not specify that x is of type :: a anyway, since that a is a different type variable than the a in the outer type signature. You can enable the ScopedTypeVariables [ghc-doc] extension, to use type variables defined in an outer scope, like:

{-# LANGUAGE ScopedTypeVariables #-}

f :: forall a . a -> a
f x = x :: a
Sign up to request clarification or add additional context in comments.

1 Comment

Ah, I was typing the x. That was what was confusing me.. I saw the :: typing at the end of the function and thought this is some way of shorthand to type the function. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.