1 {-# LANGUAGE DataKinds #-}
2 {-# LANGUAGE DefaultSignatures #-}
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 {-# LANGUAGE UndecidableInstances #-}
12 {-# OPTIONS_GHC -fno-warn-orphans #-}
13 {-# OPTIONS_GHC -fconstraint-solver-iterations=11 #-}
14 -- | Symantic for @(,)@.
15 module Language.Symantic.Compiling.Tuple2 where
17 import Control.Monad (liftM, liftM2)
18 import Data.Monoid ((<>))
20 import Data.String (IsString)
21 import Data.Text (Text)
22 import qualified Data.Tuple as Tuple
23 import Data.Type.Equality ((:~:)(Refl))
24 import Prelude hiding (fst, snd)
26 import Language.Symantic.Typing
27 import Language.Symantic.Compiling.Term
28 import Language.Symantic.Compiling.Monoid (tyMonoid)
29 import Language.Symantic.Interpreting
30 import Language.Symantic.Transforming.Trans
32 -- * Class 'Sym_Tuple2'
33 class Sym_Tuple2 term where
34 tuple2 :: term a -> term b -> term (a, b)
35 fst :: term (a, b) -> term a
36 snd :: term (a, b) -> term b
38 default tuple2 :: Trans t term => t term a -> t term b -> t term (a, b)
39 default fst :: Trans t term => t term (a, b) -> t term a
40 default snd :: Trans t term => t term (a, b) -> t term b
42 tuple2 = trans_map2 tuple2
46 type instance Sym_of_Iface (Proxy (,)) = Sym_Tuple2
47 type instance Consts_of_Iface (Proxy (,)) = Proxy (,) ': Consts_imported_by (,)
48 type instance Consts_imported_by (,) =
60 instance Sym_Tuple2 HostI where
64 instance Sym_Tuple2 TextI where
65 tuple2 (TextI a) (TextI b) =
67 let p' = precedence_Toplevel in
68 "(" <> a p' v <> ", " <> b p' v <> ")"
69 fst = textI_app1 "fst"
70 snd = textI_app1 "snd"
71 instance (Sym_Tuple2 r1, Sym_Tuple2 r2) => Sym_Tuple2 (DupI r1 r2) where
72 tuple2 = dupI2 sym_Tuple2 tuple2
73 fst = dupI1 sym_Tuple2 fst
74 snd = dupI1 sym_Tuple2 snd
76 instance Const_from Text cs => Const_from Text (Proxy (,) ': cs) where
77 const_from "(,)" k = k (ConstZ kind)
78 const_from s k = const_from s $ k . ConstS
79 instance Show_Const cs => Show_Const (Proxy (,) ': cs) where
80 show_const ConstZ{} = "(,)"
81 show_const (ConstS c) = show_const c
85 , Proj_Consts cs (Consts_imported_by (,))
88 ) => Proj_ConC cs (Proxy (,)) where
89 proj_conC _ (TyConst q :$ (TyConst c :$ a))
90 | Just Refl <- eq_skind (kind_of_const c) (SKiType `SKiArrow` SKiType `SKiArrow` SKiType)
91 , Just Refl <- proj_const c (Proxy::Proxy (,))
93 _ | Just Refl <- proj_const q (Proxy::Proxy Applicative)
94 , Just Con <- proj_con (tyMonoid :$ a) -> Just Con
95 | Just Refl <- proj_const q (Proxy::Proxy Functor) -> Just Con
96 | Just Refl <- proj_const q (Proxy::Proxy Foldable) -> Just Con
97 | Just Refl <- proj_const q (Proxy::Proxy Monad)
98 , Just Con <- proj_con (tyMonoid :$ a) -> Just Con
99 | Just Refl <- proj_const q (Proxy::Proxy Traversable) -> Just Con
101 proj_conC _ (t@(TyConst q) :$ (TyConst c :$ a :$ b))
102 | Just Refl <- eq_skind (kind_of_const c) (SKiType `SKiArrow` SKiType `SKiArrow` SKiType)
103 , Just Refl <- proj_const c (Proxy::Proxy (,))
105 _ | Just Refl <- proj_const q (Proxy::Proxy Bounded)
106 , Just Con <- proj_con (t :$ a)
107 , Just Con <- proj_con (t :$ b) -> Just Con
108 | Just Refl <- proj_const q (Proxy::Proxy Eq)
109 , Just Con <- proj_con (t :$ a)
110 , Just Con <- proj_con (t :$ b) -> Just Con
111 | Just Refl <- proj_const q (Proxy::Proxy Monoid)
112 , Just Con <- proj_con (t :$ a)
113 , Just Con <- proj_con (t :$ b) -> Just Con
114 | Just Refl <- proj_const q (Proxy::Proxy Ord)
115 , Just Con <- proj_con (t :$ a)
116 , Just Con <- proj_con (t :$ b) -> Just Con
118 proj_conC _c _q = Nothing
119 instance -- Term_fromI
121 , Lexem ast ~ LamVarName
122 , Inj_Const (Consts_of_Ifaces is) (,)
124 ) => Term_fromI is (Proxy (,)) ast where
125 term_fromI ast ctx k =
126 case ast_lexem ast of
130 _ -> Left $ Error_Term_unsupported
133 -- (,) :: a -> b -> (a, b)
134 from_ast2 ast $ \ast_a ast_b as ->
135 term_from ast_a ctx $ \ty_a (TermLC a) ->
136 term_from ast_b ctx $ \ty_b (TermLC b) ->
137 k as (tyTuple2 :$ ty_a :$ ty_b) $ TermLC $
138 \c -> tuple2 (a c) (b c)
140 -- fst :: (a, b) -> a
141 from_ast1 ast $ \ast_ab as ->
142 term_from ast_ab ctx $ \ty_ab (TermLC ab) ->
143 check_type2 tyTuple2 ast_ab ty_ab $ \Refl ty_a _ty_b ->
147 -- snd :: (a, b) -> b
148 from_ast1 ast $ \ast_ab as ->
149 term_from ast_ab ctx $ \ty_ab (TermLC ab) ->
150 check_type2 tyTuple2 ast_ab ty_ab $ \Refl _ty_a ty_b ->
154 -- | The '(,)' 'Type'
155 tyTuple2 :: Inj_Const cs (,) => Type cs (,)
156 tyTuple2 = TyConst inj_const
158 sym_Tuple2 :: Proxy Sym_Tuple2
161 syTuple2 :: IsString a => [Syntax a] -> Syntax a
162 syTuple2 = Syntax "(,)"