1 {-# LANGUAGE FlexibleInstances #-}
3 {-# LANGUAGE NoMonomorphismRestriction #-}
4 {-# LANGUAGE OverloadedStrings #-}
5 {-# LANGUAGE TypeFamilies #-}
6 {-# LANGUAGE UndecidableInstances #-}
7 module Language.Symantic.Typing.Syntax where
9 import Data.Text (Text)
10 import qualified Data.Text as Text
11 import qualified Data.List as List
12 import Data.String (IsString(..))
17 ast_lexem :: node -> Lexem node
18 ast_nodes :: node -> [node]
21 -- | Attach a location.
25 instance Functor (At ast) where
26 fmap f (At ast a) = At ast (f a)
29 = Error_Syntax_more_arguments_needed (At ast Int)
30 | Error_Syntax_too_many_arguments (At ast Int)
33 class Lift_Error_Syntax err where
34 lift_error_syntax :: Error_Syntax ast -> err ast
37 :: (AST ast, Lift_Error_Syntax err) => ast
38 -> (ast -> ast -> Either (err ast) ret)
39 -> Either (err ast) ret
43 args | length args < 2 ->
44 Left $ lift_error_syntax $
45 Error_Syntax_more_arguments_needed $
46 At (Just ast) $ 2 - length args
47 args -> Left $ lift_error_syntax $
48 Error_Syntax_too_many_arguments $
49 At (Just ast) $ length args - 2
51 :: (AST ast, Lift_Error_Syntax err) => ast
52 -> (ast -> ast -> ast -> Either (err ast) ret)
53 -> Either (err ast) ret
56 [a1, a2, a3] -> k a1 a2 a3
57 args | length args < 3 ->
58 Left $ lift_error_syntax $
59 Error_Syntax_more_arguments_needed $
60 At (Just ast) $ 3 - length args
61 args -> Left $ lift_error_syntax $
62 Error_Syntax_too_many_arguments $
63 At (Just ast) $ length args - 3
69 instance AST (Syntax a) where
70 type Lexem (Syntax a) = a
71 ast_lexem (Syntax x _) = x
72 ast_nodes (Syntax _ ns) = ns
74 -- | Custom 'Show' instance a little bit more readable
75 -- than the automatically derived one.
76 instance Show (Syntax Text) where
77 showsPrec p ast@(Syntax name args) =
78 let n = Text.unpack name in
80 Syntax _ [] -> showString n
82 showParen (p <= prec_arrow) $
83 showString (""++n++" ") .
84 showsPrec prec_arrow a
85 Syntax "(->)" [a, b] ->
86 showParen (p <= prec_arrow) $
87 showsPrec prec_arrow a .
89 showsPrec (prec_arrow + 1) b
90 Syntax "\\" [var, ty, body] ->
91 showParen (p <= prec_lambda) $
93 showsPrec prec_lambda var .
95 showsPrec prec_lambda ty .
96 showString (") -> ") .
97 showsPrec prec_lambda body
98 Syntax " " [fun, arg] ->
99 showParen (p <= prec_app) $
100 showsPrec prec_dollar fun .
102 showsPrec prec_dollar arg
103 Syntax "$" [fun, arg] ->
104 showParen (p <= prec_dollar) $
105 showsPrec prec_dollar fun .
107 showsPrec prec_dollar arg
109 showParen (p <= prec_app) $
112 showString (List.unwords $ show <$> args)
120 syBool :: IsString a => Syntax a
121 syBool = Syntax "Bool" []
122 syEq :: IsString a => [Syntax a] -> Syntax a
124 syFun :: IsString a => [Syntax a] -> Syntax a
125 syFun = Syntax "(->)"
126 syInt :: IsString a => Syntax a
127 syInt = Syntax "Int" []
128 syIO :: IsString a => [Syntax a] -> Syntax a
130 syTraversable :: IsString a => [Syntax a] -> Syntax a
131 syTraversable = Syntax "Traversable"
132 syMonad :: IsString a => [Syntax a] -> Syntax a
133 syMonad = Syntax "Monad"
134 (.>) :: IsString a => Syntax a -> Syntax a -> Syntax a
135 a .> b = syFun [a, b]