Rigid type variable in Haskell

Viewed 4566

I don't really get what is wrong with the following code.

data TypeA = TypeA

class MyClass a where
  myClassFunction :: a -> String

instance MyClass TypeA where
  myClassFunction TypeA = "TypeA"

bar :: (MyClass a) => String -> a
bar "TypeA" = TypeA 

I get following error:

   Couldn't match expected type ‘a’ with actual type ‘TypeA’
      ‘a’ is a rigid type variable bound by
          the type signature for bar :: MyClass a => String -> a
          at test.hs:9:8
    Relevant bindings include
      bar :: String -> a (bound at test.hs:10:1)
    In the expression: TypeA
    In an equation for ‘bar’: bar "TypeA" = TypeA
Failed, modules loaded: none.

I'm afraid that I'm missing something crucial about Haskell type system.

3 Answers

a should be any type, and yet you return a specific type. One way around it is to use the extension existentialQuantification. Or you extend your class as the following:

data TypeA = TypeA

class MyClass a where
  myClassFunction :: a -> String
  foo :: String -> a

instance MyClass TypeA where
  myClassFunction TypeA = "TypeA"
  foo "TypeA" = TypeA
  foo _ = error "unknown"

bar :: (MyClass a) => String -> a
bar = foo

So when you call the bar function:

bar "TypeA" :: TypeA
Related