I have a closed type family which has no catch-all case:
{-# LANGUAGE TypeFamilies #-}
type family Foo a where
Foo Bool = Int
Foo Int = Bool
Is there a way to force the type checker to reject the following program:
data T a = MkT deriving Show
x :: T (Foo String)
x = MkT
on account of the fact that there is no Foo String
type?
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.
forall is something called "type quantifier", and it gives extra meaning to polymorphic type signatures (e.g. :: a , :: a -> b , :: a -> Int , ...). While normaly forall plays a role of the "universal quantifier", it can also play a role of the "existential quantifier" (depends on the situation).
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.
Starting from GHC 8.0.1, it's possible to write:
{-# LANGUAGE TypeFamilies, DataKinds, TypeOperators, UndecidableInstances #-}
import GHC.TypeLits
type family Foo a where
Foo Bool = Int
Foo Int = Bool
Foo a = TypeError (Text "Invalid Foo " :<>: ShowType a)
data T a = MkT deriving Show
x :: T (Foo String)
x = MkT
Module can be loaded, yet you cannot use x
:
*Main> :r
[1 of 1] Compiling Main ( te.hs, interpreted )
Ok, modules loaded: Main.
*Main> x
<interactive>:18:1: error:
• Invalid Foo [Char]
• When checking the inferred type
it :: T (TypeError ...)
If you add, without a type signature
y = id x
the GHC(i) while complain during type-check:
te.hs:15:1: error:
• Invalid Foo [Char]
• When checking the inferred type
y :: T (TypeError ...)
Yet, if you give y
a type: y :: T (Foo String)
; then GHC will accept that as well.
I'm not sure whether this is a bug or feature. Type families, even closed one, cannot be arbitrarily reduced, especially in presence of UndecidableInstances
, which one needs to use TypeError
in the first place. And even something like whnf is probably not enough, if type family would reduce to Maybe (TypeError ...)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With