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 | Error_Type_Constraint_missing (At ast (EType cs))
96 deriving instance (Eq ast, Eq (Lexem ast)) => Eq (Error_Type cs ast)
97 deriving instance (Show ast, Show (Lexem ast), Show_Const cs) => Show (Error_Type cs ast)
99 -- * Class 'Type_from'
100 -- | Try to build a 'Type' from raw data.
101 class Type_from ast cs where
104 -> (forall ki_h h. Type cs ki_h h -> Either (Error_Type cs ast) ret)
105 -> Either (Error_Type cs ast) ret
109 , Const_from (Lexem ast) cs
111 ) => Type_from ast cs where
113 fromMaybe (Left $ Error_Type_Constant_unknown $ At ast ()) $
114 const_from (ast_lexem ast) $ \c -> Just $
115 go (ast_nodes ast) (TyConst c) kk
117 go :: forall ki h ret. [ast]
119 -> (forall ki' h'. Type cs ki' h' -> Either (Error_Type cs ast) ret)
120 -> Either (Error_Type cs ast) ret
122 go (ast_x:ast_xs) ty_f k =
123 type_from ast_x $ \ty_x ->
124 let ki_x = kind_of ty_x in
126 ki_f_a `SKiArrow` ki_f_b ->
127 case testEquality ki_f_a ki_x of
128 Nothing -> Left $ Error_Type_Kind_mismatch
129 (At ast $ EKind ki_f_a)
130 (At ast_x $ EKind ki_x)
132 let ty_fx = ty_f :$ ty_x in
135 case proj_con ty_f ty_x of
136 Nothing -> Left $ Error_Type_Constraint_missing $ At ast (EType ty_fx)
137 Just Dict -> go ast_xs (ty_f :~ ty_x) k
138 _ -> go ast_xs ty_fx k
139 ki -> Left $ Error_Type_Kind_not_applicable $ At ast (EKind ki)
141 syBool :: IsString a => Syntax a
142 syBool = Syntax "Bool" []
143 syEq :: IsString a => [Syntax a] -> Syntax a
145 syFun :: IsString a => [Syntax a] -> Syntax a
146 syFun = Syntax "(->)"
147 syInt :: IsString a => Syntax a
148 syInt = Syntax "Int" []
149 syIO :: IsString a => [Syntax a] -> Syntax a
151 syTraversable :: IsString a => [Syntax a] -> Syntax a
152 syTraversable = Syntax "Traversable"
153 syMonad :: IsString a => [Syntax a] -> Syntax a
154 syMonad = Syntax "Monad"
155 (.>) :: IsString a => Syntax a -> Syntax a -> Syntax a
156 a .> b = syFun [a, b]