packages feed

first-class-families 0.1.0.0 → 0.2.0.0

raw patch · 4 files changed

+144/−16 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Fcf: data BimapEither :: (a -> Exp a') -> (b -> Exp b') -> Either a b -> Exp (Either a' b')
- Fcf: data BimapPair :: (a -> Exp a') -> (b -> Exp b') -> (a, b) -> Exp (a', b')
- Fcf: data Traverse :: (a -> Exp b) -> [a] -> Exp [b]
+ Fcf: data Bimap :: (a -> Exp a') -> (b -> Exp b') -> f a b -> Exp (f a' b')
+ Fcf: data Collapse :: [Constraint] -> Exp Constraint
+ Fcf: data Cons2 :: (a, b) -> ([a], [b]) -> Exp ([a], [b])
+ Fcf: data ConstFn :: a -> b -> Exp a
+ Fcf: data Error :: Symbol -> Exp a
+ Fcf: data Filter :: (a -> Exp Bool) -> [a] -> Exp [a]
+ Fcf: data Find :: (a -> Exp Bool) -> [a] -> Exp (Maybe a)
+ Fcf: data Fst :: (a, b) -> Exp a
+ Fcf: data Head :: [a] -> Exp (Maybe a)
+ Fcf: data Length :: [a] -> Exp Nat
+ Fcf: data Map :: (a -> Exp b) -> f a -> Exp (f b)
+ Fcf: data Null :: [a] -> Exp Bool
+ Fcf: data Snd :: (a, b) -> Exp b
+ Fcf: data Tail :: [a] -> Exp (Maybe [a])
+ Fcf: data TyEq :: a -> b -> Exp Bool
+ Fcf: data Unzip :: Exp [(a, b)] -> Exp ([a], [b])
+ Fcf: data ZipWith :: (a -> b -> Exp c) -> [a] -> [b] -> Exp [c]
+ Fcf: type Lookup (a :: k) (as :: [(k, b)]) = (Map Snd (Eval (Find (TyEq a <=< Fst) as)) :: Exp (Maybe b))
+ Fcf: type Zip = ZipWith (Pure2 '(,))
- Fcf: data (&&) :: Bool -> Bool -> Exp Bool
+ Fcf: data ($) :: (a -> Exp b) -> a -> Exp b

Files

+ CHANGELOG.md view
@@ -0,0 +1,8 @@+# 0.2.0.0++- A whole bunch of basic functions, thanks to @isovector+- Remove `Traverse` (now `Map`), `BimapPair`, `BimapEither` (now `Bimap`)++# 0.1.0.0++Initial version
README.md view
@@ -1,5 +1,7 @@ # First-class type families [![Hackage](https://img.shields.io/hackage/v/first-class-families.svg)](https://hackage.haskell.org/package/first-class-families) [![Build Status](https://travis-ci.org/Lysxia/first-class-families.svg)](https://travis-ci.org/Lysxia/first-class-families) +[Haskell with only one type family](http://blog.poisson.chat/posts/2018-08-06-one-type-family.html) (blogpost)+ See `src/Fcf`.  ---
first-class-families.cabal view
@@ -1,5 +1,5 @@ name:                first-class-families-version:             0.1.0.0+version:             0.2.0.0 synopsis:   First class type families description:@@ -15,7 +15,7 @@ copyright:           2018 Li-yao Xia category:            Other build-type:          Simple-extra-source-files:  README.md+extra-source-files:  README.md, CHANGELOG.md cabal-version:       >=1.10 tested-with:   GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.3
src/Fcf.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE RankNTypes #-}@@ -30,7 +31,8 @@  module Fcf where -import Data.Kind (Type)+import Data.Kind (Type, Constraint)+import GHC.TypeLits (Symbol, Nat, type (+), TypeError, ErrorMessage(..))  -- * First-class type families @@ -72,7 +74,7 @@ data (<*>) :: Exp (a -> b) -> Exp a -> Exp b type instance Eval (f <*> e) = Eval f (Eval e) --- ** More higher-order combinators+-- ** More combinators  data Flip :: (a -> b -> Exp c) -> b -> a -> Exp c type instance Eval (Flip f y x) = Eval (f x y)@@ -80,34 +82,130 @@ data Uncurry :: (a -> b -> Exp c) -> (a, b) -> Exp c type instance Eval (Uncurry f '(x, y)) = Eval (f x y) -data BimapPair :: (a -> Exp a') -> (b -> Exp b') -> (a, b) -> Exp (a', b')-type instance Eval (BimapPair f g '(x, y)) = '(Eval (f x), Eval (g y))- data UnEither :: (a -> Exp c) -> (b -> Exp c) -> Either a b -> Exp c type instance Eval (UnEither f g ('Left  x)) = Eval (f x) type instance Eval (UnEither f g ('Right y)) = Eval (g y) -data BimapEither-  :: (a -> Exp a') -> (b -> Exp b') -> Either a b -> Exp (Either a' b')-type instance Eval (BimapEither f g ('Left  x)) = 'Left  (Eval (f x))-type instance Eval (BimapEither f g ('Right y)) = 'Right (Eval (g y))- data UnMaybe :: Exp b -> (a -> Exp b) -> Maybe a -> Exp b type instance Eval (UnMaybe y f 'Nothing) = Eval y type instance Eval (UnMaybe y f ('Just x)) = Eval (f x) +data ConstFn :: a -> b -> Exp a+type instance Eval (ConstFn a _b) = a++-- ** Tuples++data Fst :: (a, b) -> Exp a+type instance Eval (Fst '(a, _b)) = a++data Snd :: (a, b) -> Exp b+type instance Eval (Snd '(_a, b)) = b++infixr 3 ***++-- | Equivalent to 'Bimap'.+data (***) :: (b -> Exp c) -> (b' -> Exp c') -> (b, b') -> Exp (c, c')+type instance Eval ((***) f f' '(b, b')) = '(Eval (f b), Eval (f' b'))++-- ** Lists+ data Foldr :: (a -> b -> Exp b) -> b -> [a] -> Exp b type instance Eval (Foldr f y '[]) = y type instance Eval (Foldr f y (x ': xs)) = Eval (f x (Eval (Foldr f y xs))) -data Traverse :: (a -> Exp b) -> [a] -> Exp [b]-type instance Eval (Traverse f '[]) = '[]-type instance Eval (Traverse f (x ': xs)) = Eval (f x) ': Eval (Traverse f xs)- -- | N.B.: This is equivalent to a 'Foldr' flipped. data UnList :: b -> (a -> b -> Exp b) -> [a] -> Exp b type instance Eval (UnList y f xs) = Eval (Foldr f y xs) +data (++) :: [a] -> [a] -> Exp [a]+type instance Eval ((++) '[] ys) = ys+type instance Eval ((++) (x ': xs) ys) = x ': Eval ((++) xs ys)++data Filter :: (a -> Exp Bool) -> [a] -> Exp [a]+type instance Eval (Filter _p '[]) = '[]+type instance Eval (Filter p (a ': as)) =+  If (Eval (p a))+    (a ': Eval (Filter p as))+    (Eval (Filter p as))++data Head :: [a] -> Exp (Maybe a)+type instance Eval (Head '[]) = 'Nothing+type instance Eval (Head (a ': _as)) = 'Just a++data Tail :: [a] -> Exp (Maybe [a])+type instance Eval (Tail '[]) = 'Nothing+type instance Eval (Tail (_a ': as)) = 'Just as++data Null :: [a] -> Exp Bool+type instance Eval (Null '[]) = 'True+type instance Eval (Null (a ': as)) = 'False++data Length :: [a] -> Exp Nat+type instance Eval (Length '[]) = 0+type instance Eval (Length (a ': as)) = 1 + Eval (Length as)++data Find :: (a -> Exp Bool) -> [a] -> Exp (Maybe a)+type instance Eval (Find _p '[]) = 'Nothing+type instance Eval (Find p (a ': as)) =+  If (Eval (p a))+    ('Just a)+    (Eval (Find p as))++-- |+-- @+-- 'Lookup' :: k -> [(k, b)] -> 'Exp' ('Maybe' b)+-- @+type Lookup (a :: k) (as :: [(k, b)]) =+  (Map Snd (Eval (Find (TyEq a <=< Fst) as)) :: Exp (Maybe b))++data ZipWith :: (a -> b -> Exp c) -> [a] -> [b] -> Exp [c]+type instance Eval (ZipWith _f '[] _bs) = '[]+type instance Eval (ZipWith _f _as '[]) = '[]+type instance Eval (ZipWith f (a ': as) (b ': bs)) =+  Eval (f a b) ': Eval (ZipWith f as bs)++-- |+-- @+-- 'Zip' :: [a] -> [b] -> 'Exp' [(a, b)]+-- @+type Zip = ZipWith (Pure2 '(,))++data Unzip :: Exp [(a, b)] -> Exp ([a], [b])+type instance Eval (Unzip as) = Eval (Foldr Cons2 '( '[], '[]) (Eval as))++data Cons2 :: (a, b) -> ([a], [b]) -> Exp ([a], [b])+type instance Eval (Cons2 '(a, b) '(as, bs)) = '(a ': as, b ': bs)++-- ** Overloaded functions++-- | Type-level 'fmap' for type-level functors.+data Map :: (a -> Exp b) -> f a -> Exp (f b)++type instance Eval (Map f '[]) = '[]+type instance Eval (Map f (a ': as)) = Eval (f a) ': Eval (Map f as)++type instance Eval (Map f 'Nothing) = 'Nothing+type instance Eval (Map f ('Just a)) = 'Just (Eval (f a))++type instance Eval (Map f ('Left x)) = 'Left x+type instance Eval (Map f ('Right a)) = 'Right (Eval (f a))++type instance Eval (Map f '(x, a)) =+  '(x, Eval (f a))+type instance Eval (Map f '(x, y, a)) =+  '(x, y, Eval (f a))+type instance Eval (Map f '(x, y, z, a)) =+  '(x, y, z, Eval (f a))+type instance Eval (Map f '(x, y, z, w, a)) =+  '(x, y, z, w, Eval (f a))++data Bimap :: (a -> Exp a') -> (b -> Exp b') -> f a b -> Exp (f a' b')++type instance Eval (Bimap f g '(x, y)) = '(Eval (f x), Eval (g y))++type instance Eval (Bimap f g ('Left  x)) = 'Left  (Eval (f x))+type instance Eval (Bimap f g ('Right y)) = 'Right (Eval (g y))+ -- | N.B.: The order of the two branches is the opposite of "if": -- @UnBool ifFalse ifTrue bool@. --@@ -137,6 +235,26 @@ type instance Eval (a && 'False) = 'False type instance Eval ('True && b) = b type instance Eval (a && 'True) = a++-- ** Other++data Error :: Symbol -> Exp a+type instance Eval (Error msg) = TypeError ('Text msg)++data Collapse :: [Constraint] -> Exp Constraint+type instance Eval (Collapse '[]) = () ~ ()+type instance Eval (Collapse (a ': as)) = (a, Eval (Collapse as))++data TyEq :: a -> b -> Exp Bool+type instance Eval (TyEq a b) = TyEqImpl a b++type family TyEqImpl (a :: k) (b :: k) :: Bool where+  TyEqImpl a a = 'True+  TyEqImpl a b = 'False++infixr 0 $+data ($) :: (a -> Exp b) -> a -> Exp b+type instance Eval (($) f a) = Eval (f a)  -- * Helpful shorthands