4

I wish to type spec a function f' defined inside a function f so that both of their type specs refer to the same type variable. However, when I try to do this, I get a compile error from the compiler, which assumes that the m outside and the m inside are not the same type variable. Any tip on how to fix this?

f :: (Monad m) => (String -> Int -> String -> m ()) -> [String] -> m () 
f _ (x:_) = f' Nothing x
  where 
    f' :: (Maybe Int) -> String -> m () -- when I comment this line, the code compiles
    f' _ _ = return ()

main = undefined
tohava
  • 5,344
  • 1
  • 25
  • 47
  • 6
    Check http://www.haskell.org/haskellwiki/Scoped_type_variables – DJG Aug 19 '13 at 12:35
  • Thanks, this solves it. If you change this into an answer I'll mark it as correct. – tohava Aug 19 '13 at 12:43
  • For this particular example you can also get it to compile by adding a `(Monad m)` constraint to the inner type signature. – Gabriella Gonzalez Aug 19 '13 at 15:39
  • Could you **please always include [full error messages](http://ideone.com/YKXYFZ)** with your questions. :) If you look there you'll see that GHC actually suggests the same fix as in Gabriel Gonzalez's comment above. – Will Ness Aug 20 '13 at 11:41

2 Answers2

4

Check http://www.haskell.org/haskellwiki/Scoped_type_variables

From the link: Scoped Type Variables are an extension to Haskell's type system that allow free type variables to be re-used in the scope of a function.

DJG
  • 6,413
  • 4
  • 30
  • 51
1

The Haskell 98 Prelude also contains a function asTypeOf which can be used to mimic scoped type variables to a certain extent (if you use a compiler that does not support XScopedTypeVariables).

See http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:asTypeOf

scravy
  • 11,904
  • 14
  • 72
  • 127