[Haskell-cafe] pattern matching on data families constructors

Alexey Egorov electreg at list.ru
Thu Apr 25 22:20:36 CEST 2013


> Would you expect this to work?
> 
> newtype DInt a = DInt a
> newtype DBool a = DBool a
>
> type family D a
> type instance D Int = DInt Int
> type instance D Bool = DBool Bool
> 
> a :: D a -> a
> a (DInt x) = x
> a (DBool x) = x
> 
> Or even better:
> 
> data family D a
> data instance D Int = DInt1 Int | DInt2 Int
> data instance D Bool = DBool Bool
> 
> a :: D a -> a
> a (DInt1 x) = x
> a (DInt2 x) = x
> a (DBool x) = x

Yes, my question is about why different instances are different types even if they have the same type constructor (D).
I'm just find it confusing that using GADTs trick it is possible to match on different constructors.

Another confusing thing is that following works:

> data G :: * -> * where
> { GInt :: G Int
> ; GBool :: G Bool }
>
> b :: G a -> D a -> a
> b GInt (DInt x) = x
> b GBool (DBool x) = x

while quite similar doesn't:

> c :: D a -> G a -> a
> c (DInt x) GInt = x
> c (DBool x) GBool = x

However, viewing data families as "type families + per-instance newtype/data declaration" is helpful, thank you.


More information about the Haskell-Cafe mailing list