Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rigid type variable in Haskell

Tags:

haskell

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.

like image 514
Saczew Avatar asked May 29 '17 13:05

Saczew


2 Answers

(MyClass a) => String -> a

Means that the function can return any a type that's asked from it. Your implementation returns one particular type that satisfies that constraint. This is more obvious with the explicit signature:

bar :: forall a. (MyClass a) => String -> a

Read plainly, that's for every type a that satisfies MyClass, this function will take a string and return a value of that type. Your version would assume exists a instead.

like image 58
Bartek Banachewicz Avatar answered Jan 03 '23 21:01

Bartek Banachewicz


The function type MyClass a => String -> a indicates a function that can return a value of any type (with an instance of MyClass) of the caller's choosing. There is no apparent way, for example, to return a value of type Int (again, assuming MyClass Int is defined) given the value TypeA

like image 43
chepner Avatar answered Jan 03 '23 21:01

chepner