]> Git — Sourcephile - haskell/symantic.git/blob - Language/Symantic/Expr/Tuple.hs
init
[haskell/symantic.git] / Language / Symantic / Expr / Tuple.hs
1 {-# LANGUAGE DefaultSignatures #-}
2 {-# LANGUAGE FlexibleContexts #-}
3 {-# LANGUAGE FlexibleInstances #-}
4 {-# LANGUAGE MultiParamTypeClasses #-}
5 {-# LANGUAGE ScopedTypeVariables #-}
6 {-# LANGUAGE TypeFamilies #-}
7 {-# OPTIONS_GHC -fno-warn-orphans #-}
8 -- | Expression for 'Tuple'.
9 module Language.Symantic.Expr.Tuple where
10
11 import Data.Proxy (Proxy(..))
12 import Prelude hiding (maybe)
13
14 import Language.Symantic.Type
15 import Language.Symantic.Trans.Common
16 import Language.Symantic.Expr.Common
17 import Language.Symantic.Expr.Functor
18
19 -- * Class 'Sym_Tuple_Lam'
20 -- | Symantic.
21 class Sym_Tuple2 repr where
22 tuple2 :: repr a -> repr b -> repr (a, b)
23 default tuple2 :: Trans t repr => t repr a -> t repr b -> t repr (a, b)
24 tuple2 = trans_map2 tuple2
25
26 instance Constraint_Type1 Functor_with_Lambda (Type_Type1 (Proxy ((,) fst)) root) where
27 constraint_type1 _c Type_Type1{} = Just Dict
28
29 -- * Type 'Expr_Tuple2'
30 -- | Expression.
31 data Expr_Tuple2 (lam:: * -> *) (root:: *)
32 type instance Root_of_Expr (Expr_Tuple2 lam root) = root
33 type instance Type_of_Expr (Expr_Tuple2 lam root) = Type_Tuple2
34 type instance Sym_of_Expr (Expr_Tuple2 lam root) repr = (Sym_Tuple2 repr)
35 type instance Error_of_Expr ast (Expr_Tuple2 lam root) = No_Error_Expr
36
37 -- | Parsing utility to check that the given type is a 'Type_Tuple2'
38 -- or raise 'Error_Expr_Type_mismatch'.
39 check_type_tuple2
40 :: forall ast ex root ty h ret.
41 ( root ~ Root_of_Expr ex
42 , ty ~ Type_Root_of_Expr ex
43 , Lift_Type Type_Tuple2 (Type_of_Expr root)
44 , Unlift_Type Type_Tuple2 (Type_of_Expr root)
45 , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
46 (Error_of_Expr ast root)
47 )
48 => Proxy ex -> ast -> ty h
49 -> (Type_Tuple2 ty h -> Either (Error_of_Expr ast root) ret)
50 -> Either (Error_of_Expr ast root) ret
51 check_type_tuple2 ex ast ty k =
52 case unlift_type $ unType_Root ty of
53 Just ty_l -> k ty_l
54 Nothing -> Left $
55 error_expr ex $
56 Error_Expr_Type_mismatch ast
57 (Exists_Type (type_tuple2 (type_var0 SZero) (type_var0 $ SSucc SZero)
58 :: Type_Root_of_Expr ex (Var0, Var0)))
59 (Exists_Type ty)
60
61 -- | Parse 'tuple2'.
62 tuple2_from
63 :: forall root lam ty ast hs ret.
64 ( ty ~ Type_Root_of_Expr (Expr_Tuple2 lam root)
65 , Eq_Type (Type_Root_of_Expr root)
66 , Expr_from ast root
67 , Lift_Type Type_Tuple2 (Type_of_Expr root)
68 , Unlift_Type Type_Tuple2 (Type_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 ) => ast -> ast
73 -> Expr_From ast (Expr_Tuple2 lam root) hs ret
74 tuple2_from ast_a ast_b _ex _ast ctx k =
75 expr_from (Proxy::Proxy root) ast_a ctx $
76 \(ty_a::Type_Root_of_Expr root h_a) (Forall_Repr_with_Context a) ->
77 expr_from (Proxy::Proxy root) ast_b ctx $
78 \(ty_b::Type_Root_of_Expr root h_b) (Forall_Repr_with_Context b) ->
79 k (type_tuple2 ty_a ty_b) $ Forall_Repr_with_Context $
80 \c -> tuple2 (a c) (b c)