MIT licensed by Li-yao Xia
Maintained by [email protected]
This version can be pinned in stack with:first-class-families-,1574
Depends on 1 package(full list with versions):
Used by 3 packages in lts-15.3(full list with versions):

First-class type families Hackage Build Status

For example, consider this simple type family:

type family   FromMaybe (a :: k) (m :: Maybe k) :: k
type instance FromMaybe a 'Nothing  = a
type instance FromMaybe a ('Just b) = b

With first-class-families (fcfs), it translates to a data declaration and instances for a single Eval family:

import Fcf

data FromMaybe :: k -> Maybe k -> Exp k
type instance Eval (FromMaybe a 'Nothing)  = a
type instance Eval (FromMaybe a ('Just b)) = b

That way, the FromMaybe constructor can be partially applied, and passed to higher-order fcfs such as Map:

Eval (Map (FromMaybe 0) '[ 'Just 1, 'Nothing ])  =  '[ 1, 0 ] :: [Nat]

Essential language extensions:

    UndecidableInstances #-}

See also

Haskell with only one type family (blogpost)

Contributions are welcome. Feel free to open an issue or make a PR on Github!


  • Add Unfoldr, Concat, ConcatMap, Replicate, Take, Drop, TakeWhile, DropWhile, Reverse to Data.List. (gspia)
  • Change Elem, Lookup, Zip to be data instead of type synonyms.
  • Fix performance of Filter and Find.

  • Add Fcf.Utils.Case and (Fcf.Combinators.>>=) (TheMatten)
  • Deprecate Fcf.Bool.Guarded
  • GHC 8.8 compatibility

  • Modularized library

  • Fcf.Utils:

    • Add TError
    • Rename Collapse to Constraints
  • Fcf.Data.List: Added Cons, Last, Init, Elem

  • New functions (blmage)

    • LiftM, LiftM2, LiftM3
    • (<=), (>=), (<), (>)
    • Guarded, Guard((:=)), Otherwise

  • GHC 8.6 compatibility

  • More new functions, (isovector)

  • A whole bunch of basic functions (isovector)
  • Remove Traverse (now Map), BimapPair, BimapEither (now Bimap)

Initial version