1 {-# LANGUAGE UndecidableInstances #-}
2 {-# OPTIONS_GHC -fno-warn-orphans #-}
3 -- | Symantic for '(->)'.
4 module Language.Symantic.Lib.Function where
6 import Prelude hiding (const, flip, id)
7 import qualified Data.Function as Fun
8 import qualified Data.MonoTraversable as MT
10 import Language.Symantic
12 -- * Class 'Sym_Function'
13 type instance Sym (Proxy (->)) = Sym_Function
14 class Sym_Function term where
15 comp :: term (b -> c) -> term (a -> b) -> term (a -> c); infixr 9 `comp`
16 const :: term a -> term b -> term a
17 flip :: term (a -> b -> c) -> term (b -> a -> c)
18 id :: term a -> term a
19 default comp :: Sym_Function (UnT term) => Trans term => term (b -> c) -> term (a -> b) -> term (a -> c)
20 default const :: Sym_Function (UnT term) => Trans term => term a -> term b -> term a
21 default flip :: Sym_Function (UnT term) => Trans term => term (a -> b -> c) -> term (b -> a -> c)
22 default id :: Sym_Function (UnT term) => Trans term => term a -> term a
29 instance Sym_Function Eval where
31 const = eval2 Fun.const
34 instance Sym_Function View where
35 comp = viewInfix "." (infixR 9)
39 instance (Sym_Function r1, Sym_Function r2) => Sym_Function (Dup r1 r2) where
40 comp = dup2 @Sym_Function comp
41 const = dup2 @Sym_Function const
42 flip = dup1 @Sym_Function flip
43 id = dup1 @Sym_Function id
46 instance (Sym_Function term, Sym_Lambda term) => Sym_Function (BetaT term)
49 instance ClassInstancesFor (->) where
50 proveConstraintFor _c (TyApp _ q (TyApp _ z _r))
51 | Just HRefl <- proj_ConstKiTy @_ @(->) z
53 _ | Just HRefl <- proj_ConstKiTy @_ @Functor q -> Just Dict
54 | Just HRefl <- proj_ConstKiTy @_ @Applicative q -> Just Dict
55 | Just HRefl <- proj_ConstKiTy @_ @Monad q -> Just Dict
57 proveConstraintFor _c (TyApp _ q (TyApp _ (TyApp _ z _a) b))
58 | Just HRefl <- proj_ConstKiTy @_ @(->) z
60 _ | Just HRefl <- proj_ConstKiTy @_ @Monoid q
61 , Just Dict <- proveConstraint (q `tyApp` b) -> Just Dict
62 | Just HRefl <- proj_ConstKiTy @_ @MT.MonoFunctor q -> Just Dict
64 proveConstraintFor _c _q = Nothing
65 instance TypeInstancesFor (->)
68 instance Gram_Term_AtomsFor src ss g (->)
69 instance (Source src, Inj_Sym ss (->)) => ModuleFor src ss (->) where
70 moduleFor _s = ["Function"] `moduleWhere`
71 [ "const" := teFunction_const
72 , "flip" := teFunction_flip
73 , "id" := teFunction_id
74 , "." `withInfixR` 9 := teFunction_compose
75 -- , "$" `withInfixR` 0 := teFunction_app
79 tyFun :: Source src => Inj_Len vs => Type src vs (->)
80 tyFun = tyConst @(K (->)) @(->)
82 a0 :: Source src => Inj_Len vs => Inj_Kind (K a) =>
83 Type src (Proxy a ': vs) a
86 b1 :: Source src => Inj_Len vs => Inj_Kind (K b) =>
87 Type src (a ': Proxy b ': vs) b
88 b1 = tyVar "b" $ VarS varZ
90 c2 :: Source src => Inj_Len vs => Inj_Kind (K c) =>
91 Type src (a ': b ': Proxy c ': vs) c
92 c2 = tyVar "c" $ VarS $ VarS varZ
95 teFunction_compose :: TermDef (->) '[Proxy a, Proxy b, Proxy c] ((b -> c) -> (a -> b) -> (a -> c))
96 teFunction_compose = Term noConstraint ((b1 ~> c2) ~> (a0 ~> b1) ~> (a0 ~> c2)) $ teSym @(->) $ lam2 comp
98 teFunction_const :: TermDef (->) '[Proxy a, Proxy b] (a -> b -> a)
99 teFunction_const = Term noConstraint (a0 ~> b1 ~> a0) $ teSym @(->) $ lam2 const
101 teFunction_flip :: TermDef (->) '[Proxy a, Proxy b, Proxy c] ((a -> b -> c) -> (b -> a -> c))
102 teFunction_flip = Term noConstraint ((a0 ~> b1 ~> c2) ~> (b1 ~> a0 ~> c2)) $ teSym @(->) $ lam1 flip
104 teFunction_id :: TermDef (->) '[Proxy a] (a -> a)
105 teFunction_id = Term noConstraint (a0 ~> a0) $ teSym @(->) $ lam1 id