1 {-# LANGUAGE DefaultSignatures #-}
3 {-# LANGUAGE FlexibleContexts #-}
4 {-# LANGUAGE FlexibleInstances #-}
5 {-# LANGUAGE MultiParamTypeClasses #-}
6 {-# LANGUAGE Rank2Types #-}
7 {-# LANGUAGE ScopedTypeVariables #-}
8 {-# LANGUAGE TypeFamilies #-}
9 {-# LANGUAGE TypeOperators #-}
10 {-# LANGUAGE UndecidableInstances #-}
11 {-# OPTIONS_GHC -fno-warn-orphans #-}
12 -- | Expression for 'Applicative'.
13 module Language.Symantic.Expr.Applicative where
15 import Control.Applicative (Applicative)
16 import Data.Proxy (Proxy(..))
17 import Data.Type.Equality ((:~:)(Refl))
18 import Prelude hiding (Applicative(..))
20 import Language.Symantic.Type
21 import Language.Symantic.Trans.Common
22 import Language.Symantic.Expr.Root
23 import Language.Symantic.Expr.Error
24 import Language.Symantic.Expr.From
25 import Language.Symantic.Expr.Lambda
26 import Language.Symantic.Expr.Functor
28 -- * Class 'Sym_Applicative'
30 class Sym_Applicative repr where
31 pure :: Applicative f => repr a -> repr (f a)
32 -- (*>) :: Applicative f => repr (f a) -> repr (f b) -> repr (f b)
33 -- (<*) :: Applicative f => repr (f a) -> repr (f b) -> repr (f a)
35 default pure :: (Trans t repr, Applicative f) => t repr a -> t repr (f a)
36 pure = trans_map1 pure
38 -- * Class 'Sym_Applicative_Lam'
39 -- | Symantic requiring a 'Lambda'.
40 class Sym_Functor lam repr => Sym_Applicative_Lam lam repr where
41 (<*>) :: Applicative f => repr (f (Lambda lam a b)) -> repr (f a) -> repr (f b)
42 -- (*>) :: Applicative f => repr (f a) -> repr (f b) -> repr (f b)
43 -- (<*) :: Applicative f => repr (f a) -> repr (f b) -> repr (f a)
45 default (<*>) :: (Trans t repr, Applicative f) => t repr (f (Lambda lam a b)) -> t repr (f a) -> t repr (f b)
46 -- default (*>) :: (Trans t, Applicative f) => t repr (f a) -> t repr (f b) -> t repr (f b)
47 -- default (<*) :: (Trans t, Applicative f) => t repr (f a) -> t repr (f b) -> t repr (f a)
48 (<*>) = trans_map2 (<*>)
51 -- * Type 'Expr_Applicative'
53 data Expr_Applicative (lam:: * -> *) (root:: *)
54 type instance Root_of_Expr (Expr_Applicative lam root) = root
55 type instance Type_of_Expr (Expr_Applicative lam root) = No_Type
56 type instance Sym_of_Expr (Expr_Applicative lam root) repr = (Sym_Applicative repr, Sym_Applicative_Lam lam repr)
57 type instance Error_of_Expr ast (Expr_Applicative lam root) = No_Error_Expr
58 instance Constraint_Type1 Applicative (Type_Type0 px root)
59 instance Constraint_Type1 Applicative (Type_Var1 root)
60 instance Constraint_Type1 Applicative (Type_Type2 px root)
63 :: forall root ty ty_root lam ast hs ret.
64 ( ty ~ Type_Root_of_Expr (Expr_Applicative lam root)
65 , ty_root ~ Type_Root_of_Expr root
66 , Eq_Type (Type_Root_of_Expr root)
67 , Type1_from ast (Type_Root_of_Expr root)
69 , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
70 (Error_of_Expr ast root)
71 , Root_of_Expr root ~ root
72 , Constraint_Type1 Applicative ty
74 -> Expr_From ast (Expr_Applicative lam root) hs ret
75 pure_from ast_f ast_a ex ast ctx k =
76 -- pure :: Applicative f => a -> f a
77 either (\err -> Left $ error_expr ex $ Error_Expr_Type err ast) id $
78 type1_from (Proxy::Proxy ty_root) ast_f $ \_f ty_f -> Right $
79 expr_from (Proxy::Proxy root) ast_a ctx $
80 \(ty_a::Type_Root_of_Expr root h_a) (Forall_Repr_with_Context a) ->
81 let ty_fa = ty_f ty_a in
82 check_constraint1_type ex (Proxy::Proxy Applicative) ast ty_fa $ \Dict ->
83 k ty_fa $ Forall_Repr_with_Context $
87 :: forall root ty lam ast hs ret.
88 ( ty ~ Type_Root_of_Expr (Expr_Applicative lam root)
90 , Eq_Type (Type_Root_of_Expr root)
91 , Eq_Type1 (Type_Root_of_Expr root)
93 , Lift_Type (Type_Fun lam) (Type_of_Expr root)
94 , Unlift_Type (Type_Fun lam) (Type_of_Expr root)
95 , Unlift_Type1 (Type_of_Expr root)
96 , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
97 (Error_of_Expr ast root)
98 , Root_of_Expr root ~ root
99 , Constraint_Type1 Applicative ty
101 -> Expr_From ast (Expr_Applicative lam root) hs ret
102 ltstargt_from ast_fg ast_fa ex ast ctx k =
103 -- (<*>) :: Applicative f => f (a -> b) -> f a -> f b
104 expr_from (Proxy::Proxy root) ast_fg ctx $
105 \(ty_fg::Type_Root_of_Expr root h_fg) (Forall_Repr_with_Context fg) ->
106 expr_from (Proxy::Proxy root) ast_fa ctx $
107 \(ty_fa::Type_Root_of_Expr root h_fa) (Forall_Repr_with_Context fa) ->
108 check_type1 ex ast ty_fg $ \(Type_Type1 _f (ty_g::Type_Root_of_Expr root h_g), _) ->
109 check_type1 ex ast ty_fa $ \(Type_Type1 f ty_fa_a, Lift_Type1 ty_f) ->
110 check_eq_type1 ex ast ty_fg ty_fa $ \Refl ->
111 check_type_fun ex ast ty_g $ \(Type_Type2 Proxy ty_g_a ty_g_b
112 :: Type_Fun lam (Type_Root_of_Expr root) h_g) ->
113 check_constraint1_type ex (Proxy::Proxy Applicative) ast ty_fa $ \Dict ->
114 check_eq_type ex ast ty_g_a ty_fa_a $ \Refl ->
115 k (Type_Root $ ty_f $ Type_Type1 f ty_g_b) $ Forall_Repr_with_Context $
116 \c -> (<*>) (fg c) (fa c)