Type families/data families
Type families/data families
https://stackoverflow.com/questions/20870432/type-family-vs-data-family-in-brief
import Data.ByteString as S import Data.ByteString.Lazy as L -- Declare a family of type synonyms, called `Element` -- `Element` has kind `* -> *`; it takes one parameter, which we call `container` type family Element container -- ByteString is a container for Word8, so... -- The Element of a `S.ByteString` is a `Word8` type instance Element S.ByteString = Word8 -- and the Element of a `L.ByteString` is also `Word8` type instance Element L.ByteString = Word8
This is a type family - you pass different type params and get different types, ie, it's a family (of types) or a function on types. The left hand side of = and the right hand side of = - are equals in types sense and you can pass to a function expecting Word8 - a Element L.ByteString and vice versa - they are equal as types (something like a family of aliases).
Such family can be closed as well:
type family F a where F Int = Maybe Int F Bool = Int
But also there are ''data family'':
-- Declare a list-like data family data family XList a -- Declare a list-like instance for Char data instance XList Char = XCons Char (XList Char) | XNil -- Declare a number-like instance for () data instance XList () = XListUnit Int -- ERROR: "Multiple declarations of `XListUnit'" data instance XList () = XListUnit Bool -- (Note: GHCI accepts this; the new declaration just replaces the previous one.)
They are similar (types/data families) but on the right hand side - it's a new type, look, it has a constructor even! For example, XCons ... and you cannot use one type where another one was expected. Instances must not repeat by arguments (see the ERROR in the example).
Also:
<<< Usually, type synonyms are just abbreviations, but type family synonyms have added power: They can make a simple type (kind /) become a synonym of a "type with kind / -> * applied to an argument": <<<
type instance F A = B