Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Closed type families and type inference in Haskell

In GHC-7.7 (and 7.8) closed type families were introduced:

A closed type family has all of its equations defined in one place and cannot be extended, whereas an open family can have instances spread across modules. The advantage of a closed family is that its equations are tried in order, similar to a term-level function definition

I want to ask you, why the following code does not compile? GHC should be able to infer all the types - GetTheType is defined only for type X and if we comment out the marked line, the code compiles.

Is this a bug in GHC or closed type families does not have such optimizations YET?

code:

{-# LANGUAGE TypeFamilies #-}

data X = X 

type family GetTheType a where
    GetTheType X = X

class TC a where
    tc :: GetTheType a -> Int

instance TC X where
    tc X = 5 

main = do
    -- if we comment out the following line, the code compiles
    let x = tc X
    print "hello"

And the error is:

Couldn't match expected type ‛GetTheType a0’ with actual type ‛X’
The type variable ‛a0’ is ambiguous
In the first argument of ‛tc’, namely ‛X’
In the expression: tc X
like image 397
Wojciech Danilo Avatar asked Dec 23 '13 01:12

Wojciech Danilo


People also ask

What are type families in Haskell?

Indexed type families, or type families for short, are a Haskell extension supporting ad-hoc overloading of data types. Type families are parametric types that can be assigned specialized representations based on the type parameters they are instantiated with.

What is a closed type family?

A closed type family has all of its equations defined in one place and cannot be extended, whereas an open family can have instances spread across modules. The advantage of a closed family is that its equations are tried in order, similar to a term-level function definition.

Does Haskell have different types?

Everything in Haskell has a type, so the compiler can reason quite a lot about your program before compiling it. Unlike Java or Pascal, Haskell has type inference.

What is type declaration in Haskell?

Haskell has three basic ways to declare a new type: The data declaration, which defines new data types. The type declaration for type synonyms, that is, alternative names for existing types. The newtype declaration, which defines new data types equivalent to existing ones.


1 Answers

There's nothing wrong with closed type families. The problem is that not all type functions are injective.

Say, you could have this closed type function:

data X = X
data Y = Y

type family GetTheType a where
    GetTheType X = X
    GetTheType Y = X

you can't infer the argument type from the result type X.

Data families are injective, but not closed:

{-# LANGUAGE TypeFamilies #-}

data X = X

data family GetTheType a

data instance GetTheType X = RX

class TC a where
    tc :: (GetTheType a) -> Int

instance TC X where
    tc RX = 5

main = do
    let x = tc RX
    print "hello"
like image 107
mgampkay Avatar answered Sep 20 '22 18:09

mgampkay