{-# LANGUAGE Trustworthy #-}
module DeFun.Core where
import Data.Kind (Type)
type FunKind :: Type -> Type -> Type
data FunKind :: Type -> Type -> Type
type Fun a b = FunKind a b -> Type
type (~>) a b = Fun a b
infixr 0 ~>
type family App (f :: a ~> b) (x :: a) :: b
type (@@) a b = App a b
infixl 9 @@
type Lam :: (a -> Type) -> (b -> Type) -> (a ~> b) -> Type
newtype Lam a b f = Lam { forall a b (a :: a -> *) (b :: b -> *) (f :: a ~> b).
Lam a b f -> LamRep a b f
appLam :: LamRep a b f }
type a :~> b = Lam a b
infixr 0 :~>
mkLam :: LamRep a b f -> Lam a b f
mkLam :: forall {a} {b} (a :: a -> *) (b :: b -> *) (f :: a ~> b).
LamRep a b f -> Lam a b f
mkLam = LamRep a b f -> Lam a b f
forall {a} {b} (a :: a -> *) (b :: b -> *) (f :: a ~> b).
LamRep a b f -> Lam a b f
Lam
type LamRep :: (a -> Type) -> (b -> Type) -> (a ~> b) -> Type
type LamRep a b fun = forall x. a x -> b (fun @@ x)
(@@) :: Lam a b f -> a x -> b (f @@ x)
Lam a b f
f @@ :: forall {a} {k} (a :: a -> *) (b :: k -> *) (f :: a ~> k) (x :: a).
Lam a b f -> a x -> b (f @@ x)
@@ a x
x = Lam a b f -> LamRep a b f
forall a b (a :: a -> *) (b :: b -> *) (f :: a ~> b).
Lam a b f -> LamRep a b f
appLam Lam a b f
f a x
x
type Lam2 a b c fun = Lam a (b :~> c) fun
type Lam3 a b c d fun = Lam a (b :~> c :~> d) fun
type LamRep2 :: (a -> Type) -> (b -> Type) -> (c -> Type) -> (a ~> b ~> c) -> Type
type LamRep2 a b c fun = forall x y. a x -> b y -> c (fun @@ x @@ y)
type LamRep3 :: (a -> Type) -> (b -> Type) -> (c -> Type) -> (d -> Type) -> (a ~> b ~> c ~> d) -> Type
type LamRep3 a b c d fun = forall x y z. a x -> b y -> c z -> d (fun @@ x @@ y @@ z)
pattern Lam2 :: LamRep2 a b c fun -> Lam2 a b c fun
pattern $mLam2 :: forall {r} {a1} {a2} {b1} {a3 :: a1 -> *} {b2 :: a2 -> *}
{c :: b1 -> *} {fun :: a1 ~> (a2 ~> b1)}.
Lam2 a3 b2 c fun -> (LamRep2 a3 b2 c fun -> r) -> ((# #) -> r) -> r
$bLam2 :: forall {a1} {a2} {b1} (a3 :: a1 -> *) (b2 :: a2 -> *)
(c :: b1 -> *) (fun :: a1 ~> (a2 ~> b1)).
LamRep2 a3 b2 c fun -> Lam2 a3 b2 c fun
Lam2 f <- (appLam2 -> f)
where Lam2 LamRep2 a3 b2 c fun
f = LamRep2 a3 b2 c fun -> Lam2 a3 b2 c fun
forall {a1} {a2} {b1} (a3 :: a1 -> *) (b2 :: a2 -> *)
(c :: b1 -> *) (fun :: a1 ~> (a2 ~> b1)).
LamRep2 a3 b2 c fun -> Lam2 a3 b2 c fun
mkLam2 a3 x -> b2 y -> c ((fun @@ x) @@ y)
LamRep2 a3 b2 c fun
f
pattern Lam3 :: LamRep3 a b c d fun -> Lam3 a b c d fun
pattern $mLam3 :: forall {r} {a1} {a2} {a3} {b1} {a4 :: a1 -> *} {b2 :: a2 -> *}
{c :: a3 -> *} {d :: b1 -> *} {fun :: a1 ~> (a2 ~> (a3 ~> b1))}.
Lam3 a4 b2 c d fun
-> (LamRep3 a4 b2 c d fun -> r) -> ((# #) -> r) -> r
$bLam3 :: forall {a1} {a2} {a3} {b1} (a4 :: a1 -> *) (b2 :: a2 -> *)
(c :: a3 -> *) (d :: b1 -> *) (fun :: a1 ~> (a2 ~> (a3 ~> b1))).
LamRep3 a4 b2 c d fun -> Lam3 a4 b2 c d fun
Lam3 f <- (appLam3 -> f)
where Lam3 LamRep3 a4 b2 c d fun
f = LamRep3 a4 b2 c d fun -> Lam3 a4 b2 c d fun
forall {a1} {a2} {a3} {b1} (a4 :: a1 -> *) (b2 :: a2 -> *)
(c :: a3 -> *) (d :: b1 -> *) (fun :: a1 ~> (a2 ~> (a3 ~> b1))).
LamRep3 a4 b2 c d fun -> Lam3 a4 b2 c d fun
mkLam3 a4 x -> b2 y -> c z -> d (((fun @@ x) @@ y) @@ z)
LamRep3 a4 b2 c d fun
f
mkLam2 :: LamRep2 a b c fun -> Lam2 a b c fun
mkLam2 :: forall {a1} {a2} {b1} (a3 :: a1 -> *) (b2 :: a2 -> *)
(c :: b1 -> *) (fun :: a1 ~> (a2 ~> b1)).
LamRep2 a3 b2 c fun -> Lam2 a3 b2 c fun
mkLam2 LamRep2 a b c fun
f = LamRep a (b :~> c) fun -> Lam a (b :~> c) fun
forall {a} {b} (a :: a -> *) (b :: b -> *) (f :: a ~> b).
LamRep a b f -> Lam a b f
Lam (\a x
x -> LamRep b c (fun @@ x) -> (:~>) b c (fun @@ x)
forall {a} {b} (a :: a -> *) (b :: b -> *) (f :: a ~> b).
LamRep a b f -> Lam a b f
Lam (a x -> b x -> c (App (fun @@ x) x)
LamRep2 a b c fun
f a x
x))
appLam2 :: Lam2 a b c fun -> LamRep2 a b c fun
appLam2 :: forall {a} {b} {c} (a :: a -> *) (b :: b -> *) (c :: c -> *)
(fun :: a ~> (b ~> c)).
Lam2 a b c fun -> LamRep2 a b c fun
appLam2 Lam2 a b c fun
f a x
x b y
y = Lam2 a b c fun
f Lam2 a b c fun -> a x -> Lam b c (App fun x)
forall {a} {k} (a :: a -> *) (b :: k -> *) (f :: a ~> k) (x :: a).
Lam a b f -> a x -> b (f @@ x)
@@ a x
x Lam b c (App fun x) -> b y -> c (App (App fun x) y)
forall {a} {k} (a :: a -> *) (b :: k -> *) (f :: a ~> k) (x :: a).
Lam a b f -> a x -> b (f @@ x)
@@ b y
y
mkLam3 :: LamRep3 a b c d fun -> Lam3 a b c d fun
mkLam3 :: forall {a1} {a2} {a3} {b1} (a4 :: a1 -> *) (b2 :: a2 -> *)
(c :: a3 -> *) (d :: b1 -> *) (fun :: a1 ~> (a2 ~> (a3 ~> b1))).
LamRep3 a4 b2 c d fun -> Lam3 a4 b2 c d fun
mkLam3 LamRep3 a b c d fun
f = LamRep a (b :~> (c :~> d)) fun -> Lam a (b :~> (c :~> d)) fun
forall {a} {b} (a :: a -> *) (b :: b -> *) (f :: a ~> b).
LamRep a b f -> Lam a b f
Lam (\a x
x -> LamRep2 b c d (fun @@ x) -> (:~>) b (c :~> d) (fun @@ x)
forall {a1} {a2} {b1} (a3 :: a1 -> *) (b2 :: a2 -> *)
(c :: b1 -> *) (fun :: a1 ~> (a2 ~> b1)).
LamRep2 a3 b2 c fun -> Lam2 a3 b2 c fun
mkLam2 (a x -> b x -> c y -> d (App (App (fun @@ x) x) y)
LamRep3 a b c d fun
f a x
x))
appLam3 :: Lam3 a b c d fun -> LamRep3 a b c d fun
appLam3 :: forall {a} {b} {c} {d} (a :: a -> *) (b :: b -> *) (c :: c -> *)
(d :: d -> *) (fun :: a ~> (b ~> (c ~> d))).
Lam3 a b c d fun -> LamRep3 a b c d fun
appLam3 Lam3 a b c d fun
f a x
x b y
y c z
z = Lam3 a b c d fun
f Lam3 a b c d fun -> a x -> Lam b (Lam c d) (App fun x)
forall {a} {k} (a :: a -> *) (b :: k -> *) (f :: a ~> k) (x :: a).
Lam a b f -> a x -> b (f @@ x)
@@ a x
x Lam b (Lam c d) (App fun x) -> b y -> Lam c d (App (App fun x) y)
forall {a} {k} (a :: a -> *) (b :: k -> *) (f :: a ~> k) (x :: a).
Lam a b f -> a x -> b (f @@ x)
@@ b y
y Lam c d (App (App fun x) y) -> c z -> d (App (App (App fun x) y) z)
forall {a} {k} (a :: a -> *) (b :: k -> *) (f :: a ~> k) (x :: a).
Lam a b f -> a x -> b (f @@ x)
@@ c z
z
type Con1 :: (a -> b) -> a ~> b
data Con1 con arg
type instance App (Con1 f) x = f x
type Con2 :: (a -> b -> c) -> a ~> b ~> c
data Con2 con arg
type instance App (Con2 f) arg = Con1 (f arg)
type Con3 :: (a -> b -> c -> d) -> a ~> b ~> c ~> d
data Con3 con arg
type instance App (Con3 f) arg = Con2 (f arg)
con1 :: LamRep a b (Con1 con) -> Lam a b (Con1 con)
con1 :: forall {a} {b} (a :: a -> *) (b :: b -> *) (con :: a -> b).
LamRep a b (Con1 con) -> Lam a b (Con1 con)
con1 = LamRep a b (Con1 con) -> Lam a b (Con1 con)
forall {a} {b} (a :: a -> *) (b :: b -> *) (f :: a ~> b).
LamRep a b f -> Lam a b f
mkLam
con2 :: LamRep2 a b c (Con2 con) -> Lam2 a b c (Con2 con)
con2 :: forall {a} {b} {c} (a :: a -> *) (b :: b -> *) (c :: c -> *)
(con :: a -> b -> c).
LamRep2 a b c (Con2 con) -> Lam2 a b c (Con2 con)
con2 = LamRep2 a b c (Con2 con) -> Lam2 a b c (Con2 con)
forall {a1} {a2} {b1} (a3 :: a1 -> *) (b2 :: a2 -> *)
(c :: b1 -> *) (fun :: a1 ~> (a2 ~> b1)).
LamRep2 a3 b2 c fun -> Lam2 a3 b2 c fun
mkLam2
con3 :: LamRep3 a b c d (Con3 con) -> Lam3 a b c d (Con3 con)
con3 :: forall {a} {b} {c} {d} (a :: a -> *) (b :: b -> *) (c :: c -> *)
(d :: d -> *) (con :: a -> b -> c -> d).
LamRep3 a b c d (Con3 con) -> Lam3 a b c d (Con3 con)
con3 = LamRep3 a b c d (Con3 con) -> Lam3 a b c d (Con3 con)
forall {a1} {a2} {a3} {b1} (a4 :: a1 -> *) (b2 :: a2 -> *)
(c :: a3 -> *) (d :: b1 -> *) (fun :: a1 ~> (a2 ~> (a3 ~> b1))).
LamRep3 a4 b2 c d fun -> Lam3 a4 b2 c d fun
mkLam3