nicolas
nicolas

Reputation: 9805

type class and binding reuse inside expressions in haskell

I am not really sure why the two intermediate expressions do not type check. The type checker seems to freshen new type bindings for each occurence of m. is there an extension to allow reusing the name m in all those locations?

test ::  MonadPlus m => m a
test =
    let r = mzero :: m a  -- fails 
    in let r' :: m a = mzero  -- fails
       in  mzero

Upvotes: 1

Views: 82

Answers (1)

leftaroundabout
leftaroundabout

Reputation: 120711

{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UnicodeSyntax       #-}

test :: ∀ m a . MonadPlus m => m a
test =
    let r = mzero :: m a
    in let r' :: m a = mzero
       in  mzero

If you don't like non-ASCII characters in your code, you can also omit the -XUnicodeSyntax and use the forall keyword in place of ∀.

What this keyword does is,

  1. it introduces the new type variables m and a, as universally quantified. Now, usually Haskell just assumes that any type variable which hasn't yet been mentioned in the same(!) signature is universal. But
  2. it disables automatic introduction of type variables, within the whole context scope. This includes also r = mzero :: m a, so at that point GHC knows it's not supposed to introduce m and a as new variables, but re-use the same m and a as in the signature of test.

Upvotes: 3

Related Questions