1 {-# LANGUAGE DataKinds #-}
2 {-# LANGUAGE PolyKinds #-}
3 {-# LANGUAGE ConstraintKinds #-}
4 {-# LANGUAGE FlexibleContexts #-}
5 {-# LANGUAGE FlexibleInstances #-}
7 {-# LANGUAGE NoMonomorphismRestriction #-}
8 {-# LANGUAGE MultiParamTypeClasses #-}
9 {-# LANGUAGE OverloadedStrings #-}
10 {-# LANGUAGE Rank2Types #-}
11 {-# LANGUAGE ScopedTypeVariables #-}
12 {-# LANGUAGE StandaloneDeriving #-}
13 {-# LANGUAGE TypeFamilies #-}
14 {-# LANGUAGE UndecidableInstances #-}
15 module Language.Symantic.Typing.Syntax where
17 import qualified Data.List as List
19 import Data.Type.Equality
20 import Data.String (IsString(..))
22 import Language.Symantic.Typing.Kind
23 import Language.Symantic.Typing.Constant
24 import Language.Symantic.Typing.Type
25 import Language.Symantic.Typing.Constraint
30 ast_lexem :: node -> Lexem node
31 ast_nodes :: node -> [node]
33 instance AST (Syntax a) where
34 type Lexem (Syntax a) = a
35 ast_lexem (Syntax x _) = x
36 ast_nodes (Syntax _ ns) = ns
39 -- | Attach a location.
43 instance Functor (At ast) where
44 fmap f (At ast a) = At ast (f a)
51 -- | Custom 'Show' instance a little bit more readable
52 -- than the automatically derived one.
53 instance Show (Syntax String) where
54 showsPrec p ast@(Syntax n args) =
56 Syntax _ [] -> showString n
58 showParen (p <= prec_arrow) $
59 showString (""++n++" ") .
60 showsPrec prec_arrow a
61 Syntax "(->)" [a, b] ->
62 showParen (p <= prec_arrow) $
63 showsPrec prec_arrow a .
65 showsPrec (prec_arrow + 1) b
66 Syntax "\\" [var, ty, body] ->
67 showParen (p <= prec_lambda) $
69 showsPrec prec_lambda var .
71 showsPrec prec_lambda ty .
72 showString (") -> ") .
73 showsPrec prec_lambda body
74 Syntax "$" [fun, arg] ->
75 showParen (p <= prec_dollar) $
76 showsPrec prec_dollar fun .
78 showsPrec prec_dollar arg
80 showParen (p <= prec_app) $
83 showString (List.unwords $ show <$> args)
90 -- * Type 'Error_Type'
91 data Error_Type cs ast
92 = Error_Type_Constant_unknown (At ast ())
93 | Error_Type_Kind_mismatch (At ast EKind) (At ast EKind)
94 | Error_Type_Kind_not_applicable (At ast EKind)
95 deriving instance (Eq ast, Eq (Lexem ast)) => Eq (Error_Type cs ast)
96 deriving instance (Show ast, Show (Lexem ast), Show_Const cs) => Show (Error_Type cs ast)
98 -- * Class 'Type_from'
99 -- | Try to build a 'Type' from raw data.
100 class Type_from ast cs where
103 -> (forall ki_h h. Type cs ki_h h -> Either (Error_Type cs ast) ret)
104 -> Either (Error_Type cs ast) ret
108 , Const_from (Lexem ast) cs
110 ) => Type_from ast cs where
112 fromMaybe (Left $ Error_Type_Constant_unknown $ At ast ()) $
113 const_from (ast_lexem ast) $ \c -> Just $
114 go (ast_nodes ast) (TyConst c) kk
116 go :: forall ki h ret. [ast]
118 -> (forall ki' h'. Type cs ki' h' -> Either (Error_Type cs ast) ret)
119 -> Either (Error_Type cs ast) ret
121 go (ast_x:ast_xs) ty_f k =
122 type_from ast_x $ \ty_x ->
124 ki_f_a `SKiArrow` _ki_f_b ->
125 let ki_x = kind_of ty_x in
126 case testEquality ki_f_a ki_x of
127 Just Refl -> go ast_xs (ty_f :$ ty_x) k
128 Nothing -> Left $ Error_Type_Kind_mismatch
129 (At ast $ EKind ki_f_a)
130 (At ast_x $ EKind ki_x)
131 ki -> Left $ Error_Type_Kind_not_applicable $ At ast (EKind ki)
133 syBool :: IsString a => Syntax a
134 syBool = Syntax "Bool" []
135 syEq :: IsString a => [Syntax a] -> Syntax a
137 syFun :: IsString a => [Syntax a] -> Syntax a
138 syFun = Syntax "(->)"
139 syInt :: IsString a => Syntax a
140 syInt = Syntax "Int" []
141 syIO :: IsString a => [Syntax a] -> Syntax a
143 syTraversable :: IsString a => [Syntax a] -> Syntax a
144 syTraversable = Syntax "Traversable"
145 syMonad :: IsString a => [Syntax a] -> Syntax a
146 syMonad = Syntax "Monad"
147 (.>) :: IsString a => Syntax a -> Syntax a -> Syntax a
148 a .> b = syFun [a, b]