{-# LANGUAGE
DataKinds,
PolyKinds,
TypeFamilies,
TypeInType,
TypeOperators,
UndecidableInstances #-}
module Fcf.Combinators
( Pure
, Pure1
, Pure2
, Pure3
, type (=<<)
, type (<=<)
, LiftM
, LiftM2
, LiftM3
, Join
, type (<$>)
, type (<*>)
, Flip
, ConstFn
, type ($)
) where
import Fcf.Core
infixl 1 >>=
infixr 1 =<<, <=<
infixl 4 <$>, <*>
data Pure :: a -> Exp a
type instance Eval (Pure x) = x
data Pure1 :: (a -> b) -> a -> Exp b
type instance Eval (Pure1 f x) = f x
data Pure2 :: (a -> b -> c) -> a -> b -> Exp c
type instance Eval (Pure2 f x y) = f x y
data Pure3 :: (a -> b -> c -> d) -> a -> b -> c -> Exp d
type instance Eval (Pure3 f x y z) = f x y z
data (=<<) :: (a -> Exp b) -> Exp a -> Exp b
type instance Eval (k =<< e) = Eval (k (Eval e))
data (>>=) :: Exp a -> (a -> Exp b) -> Exp b
type instance Eval (e >>= k) = Eval (k (Eval e))
data (<=<) :: (b -> Exp c) -> (a -> Exp b) -> a -> Exp c
type instance Eval ((f <=< g) x) = Eval (f (Eval (g x)))
type LiftM = (=<<)
data LiftM2 :: (a -> b -> Exp c) -> Exp a -> Exp b -> Exp c
type instance Eval (LiftM2 f x y) = Eval (f (Eval x) (Eval y))
data LiftM3 :: (a -> b -> c -> Exp d) -> Exp a -> Exp b -> Exp c -> Exp d
type instance Eval (LiftM3 f x y z) = Eval (f (Eval x) (Eval y) (Eval z))
data Join :: Exp (Exp a) -> Exp a
type instance Eval (Join e) = Eval (Eval e)
data (<$>) :: (a -> b) -> Exp a -> Exp b
type instance Eval (f <$> e) = f (Eval e)
data (<*>) :: Exp (a -> b) -> Exp a -> Exp b
type instance Eval (f <*> e) = Eval f (Eval e)
data Flip :: (a -> b -> Exp c) -> b -> a -> Exp c
type instance Eval (Flip f y x) = Eval (f x y)
data ConstFn :: a -> b -> Exp a
type instance Eval (ConstFn a _b) = a
data ($) :: (a -> Exp b) -> a -> Exp b
type instance Eval (($) f a) = Eval (f a)
infixr 0 $