]> Git — Sourcephile - haskell/symantic.git/blob - Language/Symantic/Expr/Applicative.hs
Eq, Ord
[haskell/symantic.git] / Language / Symantic / Expr / Applicative.hs
1 {-# LANGUAGE DefaultSignatures #-}
2 {-# LANGUAGE GADTs #-}
3 {-# LANGUAGE FlexibleContexts #-}
4 {-# LANGUAGE FlexibleInstances #-}
5 {-# LANGUAGE MultiParamTypeClasses #-}
6 {-# LANGUAGE OverloadedStrings #-}
7 {-# LANGUAGE Rank2Types #-}
8 {-# LANGUAGE ScopedTypeVariables #-}
9 {-# LANGUAGE TypeFamilies #-}
10 {-# LANGUAGE TypeOperators #-}
11 {-# OPTIONS_GHC -fno-warn-orphans #-}
12 -- | Expression for 'Applicative'.
13 module Language.Symantic.Expr.Applicative where
14
15 import Control.Applicative (Applicative)
16 import qualified Control.Applicative as Applicative
17 import Control.Monad
18 import qualified Data.Function as Fun
19 import Data.Monoid
20 import Data.Proxy (Proxy(..))
21 import Data.Type.Equality ((:~:)(Refl))
22 import Prelude hiding (Functor(..), (<$>), Applicative(..), id, const)
23
24 import Language.Symantic.Type
25 import Language.Symantic.Repr
26 import Language.Symantic.Trans.Common
27 import Language.Symantic.Expr.Root
28 import Language.Symantic.Expr.Error
29 import Language.Symantic.Expr.From
30 import Language.Symantic.Expr.Lambda
31 import Language.Symantic.Expr.Functor
32
33 -- * Class 'Sym_Applicative'
34 -- | Symantic.
35 class Sym_Functor repr => Sym_Applicative repr where
36 pure :: Applicative f => repr a -> repr (f a)
37 (<*>) :: Applicative f => repr (f ((->) a b)) -> repr (f a) -> repr (f b)
38 default pure :: (Trans t repr, Applicative f) => t repr a -> t repr (f a)
39 default (<*>) :: (Trans t repr, Applicative f)
40 => t repr (f ((->) a b)) -> t repr (f a) -> t repr (f b)
41 pure = trans_map1 pure
42 (<*>) = trans_map2 (<*>)
43 (*>) :: Applicative f => repr (f a) -> repr (f b) -> repr (f b)
44 (<*) :: Applicative f => repr (f a) -> repr (f b) -> repr (f a)
45 x *> y = (lam Fun.id <$ x) <*> y
46 x <* y = (lam (lam . Fun.const) <$> x) <*> y
47 infixl 4 *>
48 infixl 4 <*
49 infixl 4 <*>
50 instance Sym_Applicative Repr_Host where
51 pure = liftM Applicative.pure
52 (<*>) = liftM2 (Applicative.<*>)
53 instance Sym_Applicative Repr_Text where
54 pure = repr_text_app1 "pure"
55 (<*>) (Repr_Text fg) (Repr_Text fa) =
56 Repr_Text $ \p v ->
57 let p' = precedence_LtStarGt in
58 paren p p' $ fg p' v <> " <*> " <> fa p' v
59 precedence_LtStarGt :: Precedence
60 precedence_LtStarGt = Precedence 4
61 instance
62 ( Sym_Applicative r1
63 , Sym_Applicative r2
64 ) => Sym_Applicative (Dup r1 r2) where
65 pure (a1 `Dup` a2) =
66 pure a1 `Dup` pure a2
67 (<*>) (f1 `Dup` f2) (m1 `Dup` m2) =
68 (<*>) f1 m1 `Dup` (<*>) f2 m2
69
70 -- * Type 'Expr_Applicative'
71 -- | Expression.
72 data Expr_Applicative (root:: *)
73 type instance Root_of_Expr (Expr_Applicative root) = root
74 type instance Type_of_Expr (Expr_Applicative root) = No_Type
75 type instance Sym_of_Expr (Expr_Applicative root) repr = (Sym_Applicative repr)
76 type instance Error_of_Expr ast (Expr_Applicative root) = No_Error_Expr
77
78 -- | Parse 'pure'.
79 pure_from
80 :: forall root ty ast hs ret.
81 ( ty ~ Type_Root_of_Expr (Expr_Applicative root)
82 , Type0_Eq ty
83 , Type1_From ast ty
84 , Expr_From ast root
85 , Error_Expr_Lift (Error_Expr (Error_of_Type ast ty) ty ast)
86 (Error_of_Expr ast root)
87 , Root_of_Expr root ~ root
88 , Type1_Constraint Applicative ty
89 ) => ast -> ast
90 -> ExprFrom ast (Expr_Applicative root) hs ret
91 pure_from ast_f ast_a ex ast ctx k =
92 -- pure :: Applicative f => a -> f a
93 either (\err -> Left $ error_expr ex $ Error_Expr_Type err ast) Fun.id $
94 type1_from (Proxy::Proxy ty) ast_f $ \_f ty_f -> Right $
95 expr_from (Proxy::Proxy root) ast_a ctx $
96 \(ty_a::ty h_a) (Forall_Repr_with_Context a) ->
97 let ty_fa = ty_f ty_a in
98 check_type1_constraint ex (Proxy::Proxy Applicative) ast ty_fa $ \Dict ->
99 k ty_fa $ Forall_Repr_with_Context $
100 \c -> pure (a c)
101
102 -- | Parse '<*>'.
103 ltstargt_from
104 :: forall root ty ast hs ret.
105 ( ty ~ Type_Root_of_Expr (Expr_Applicative root)
106 , Expr_From ast root
107 , Type0_Eq ty
108 , Type1_Eq ty
109 , Type0_Lift Type_Fun (Type_of_Expr root)
110 , Type0_Unlift Type_Fun (Type_of_Expr root)
111 , Type1_Unlift (Type_of_Expr root)
112 , Error_Expr_Lift (Error_Expr (Error_of_Type ast ty) ty ast)
113 (Error_of_Expr ast root)
114 , Root_of_Expr root ~ root
115 , Type1_Constraint Applicative ty
116 ) => ast -> ast
117 -> ExprFrom ast (Expr_Applicative root) hs ret
118 ltstargt_from ast_fg ast_fa ex ast ctx k =
119 -- (<*>) :: Applicative f => f (a -> b) -> f a -> f b
120 expr_from (Proxy::Proxy root) ast_fg ctx $
121 \(ty_fg::ty h_fg) (Forall_Repr_with_Context fg) ->
122 expr_from (Proxy::Proxy root) ast_fa ctx $
123 \(ty_fa::ty h_fa) (Forall_Repr_with_Context fa) ->
124 check_type1 ex ast ty_fg $ \(Type1 _f (ty_g::ty h_g), _) ->
125 check_type1 ex ast ty_fa $ \(Type1 f ty_fa_a, Type1_Lift ty_f) ->
126 check_type1_eq ex ast ty_fg ty_fa $ \Refl ->
127 check_type_fun ex ast ty_g $ \(Type2 Proxy ty_g_a ty_g_b
128 :: Type_Fun ty h_g) ->
129 check_type1_constraint ex (Proxy::Proxy Applicative) ast ty_fa $ \Dict ->
130 check_type0_eq ex ast ty_g_a ty_fa_a $ \Refl ->
131 k (Type_Root $ ty_f $ Type1 f ty_g_b) $ Forall_Repr_with_Context $
132 \c -> (<*>) (fg c) (fa c)