2012-04-19 06:32:10 +00:00
|
|
|
|
2012-11-23 04:30:37 +00:00
|
|
|
module Types.Types where
|
2012-04-19 06:32:10 +00:00
|
|
|
|
2012-12-25 08:39:18 +00:00
|
|
|
import Context
|
2012-07-19 11:51:57 +00:00
|
|
|
import Data.Char (isDigit)
|
|
|
|
import Data.List (intercalate,isPrefixOf)
|
2012-05-11 10:28:56 +00:00
|
|
|
import qualified Data.Set as Set
|
2012-12-25 08:39:18 +00:00
|
|
|
import qualified Data.Map as Map
|
2012-05-11 10:28:56 +00:00
|
|
|
|
|
|
|
type X = Int
|
2012-04-19 06:32:10 +00:00
|
|
|
|
2012-07-19 11:51:57 +00:00
|
|
|
data Type = LambdaT Type Type
|
2012-05-11 10:28:56 +00:00
|
|
|
| VarT X
|
2012-04-19 06:32:10 +00:00
|
|
|
| ADT String [Type]
|
2012-12-25 08:39:18 +00:00
|
|
|
| EmptyRecord
|
|
|
|
| RecordT (Map.Map String [Type]) Type
|
2012-08-09 14:38:18 +00:00
|
|
|
| Super (Set.Set Type)
|
2012-05-11 10:28:56 +00:00
|
|
|
deriving (Eq, Ord)
|
|
|
|
|
2012-12-25 08:39:18 +00:00
|
|
|
data Scheme = Forall [X] [Context Constraint] Type deriving (Eq, Ord)
|
2012-05-21 02:24:35 +00:00
|
|
|
|
2012-07-19 11:51:57 +00:00
|
|
|
data Constraint = Type :=: Type
|
2012-08-09 14:38:18 +00:00
|
|
|
| Type :<: Type
|
|
|
|
| X :<<: Scheme
|
2012-07-19 11:51:57 +00:00
|
|
|
deriving (Eq, Ord, Show)
|
|
|
|
|
2013-01-03 08:30:28 +00:00
|
|
|
recordT :: [(String,Type)] -> Map.Map String [Type]
|
|
|
|
recordT fields =
|
|
|
|
foldl (\r (x,t) -> Map.insertWith (++) x [t] r) Map.empty fields
|
2012-07-19 11:51:57 +00:00
|
|
|
|
2013-01-14 08:15:14 +00:00
|
|
|
recordOf :: [(String,Type)] -> Type
|
|
|
|
recordOf fields = RecordT (recordT fields) EmptyRecord
|
|
|
|
|
2013-01-03 08:30:28 +00:00
|
|
|
tipe t = ADT t []
|
2012-07-19 11:51:57 +00:00
|
|
|
|
|
|
|
int = tipe "Int"
|
|
|
|
float = tipe "Float"
|
2012-08-09 14:38:18 +00:00
|
|
|
number = Super (Set.fromList [ int, float ])
|
2012-07-19 11:51:57 +00:00
|
|
|
|
|
|
|
char = tipe "Char"
|
|
|
|
bool = tipe "Bool"
|
|
|
|
|
2012-07-21 23:50:35 +00:00
|
|
|
string = listOf char -- tipe "String"
|
2012-07-19 11:51:57 +00:00
|
|
|
text = tipe "Text"
|
|
|
|
|
2012-12-02 05:12:51 +00:00
|
|
|
time = float --tipe "Time"
|
2012-11-29 06:16:08 +00:00
|
|
|
date = tipe "Date"
|
|
|
|
month = tipe "Month"
|
|
|
|
day = tipe "Day"
|
2012-07-19 11:51:57 +00:00
|
|
|
|
|
|
|
element = tipe "Element"
|
|
|
|
direction = tipe "Direction"
|
|
|
|
form = tipe "Form"
|
|
|
|
line = tipe "Line"
|
|
|
|
shape = tipe "Shape"
|
|
|
|
color = tipe "Color"
|
2012-09-18 15:18:49 +00:00
|
|
|
position = tipe "Position"
|
|
|
|
location = tipe "Location"
|
2012-05-21 02:24:35 +00:00
|
|
|
|
|
|
|
listOf t = ADT "List" [t]
|
|
|
|
signalOf t = ADT "Signal" [t]
|
2012-05-18 03:16:16 +00:00
|
|
|
tupleOf ts = ADT ("Tuple" ++ show (length ts)) ts
|
2012-06-28 08:52:47 +00:00
|
|
|
maybeOf t = ADT "Maybe" [t]
|
2013-02-09 18:45:16 +00:00
|
|
|
eitherOf a b = ADT "Either" [a,b]
|
2012-07-19 12:22:31 +00:00
|
|
|
pairOf t = tupleOf [t,t]
|
|
|
|
point = pairOf int
|
2012-08-09 14:38:18 +00:00
|
|
|
appendable t = Super (Set.fromList [ string, text, listOf t ])
|
2012-11-29 06:16:08 +00:00
|
|
|
comparable = Super (Set.fromList [ int, float, char, string, time, date ])
|
2012-06-28 08:52:47 +00:00
|
|
|
|
2012-07-19 11:51:57 +00:00
|
|
|
jsBool = tipe "JSBool"
|
|
|
|
jsNumber = tipe "JSNumber"
|
|
|
|
jsString = tipe "JSString"
|
|
|
|
jsElement = tipe "JSElement"
|
2012-06-28 08:52:47 +00:00
|
|
|
jsArray t = ADT "JSArray" [t]
|
|
|
|
jsTuple ts = ADT ("JSTuple" ++ show (length ts)) ts
|
2012-07-28 20:59:51 +00:00
|
|
|
jsonValue = tipe "JsonValue"
|
|
|
|
jsonObject = tipe "JsonObject"
|
2012-05-18 03:16:16 +00:00
|
|
|
|
|
|
|
infixr ==>
|
|
|
|
t1 ==> t2 = LambdaT t1 t2
|
|
|
|
|
|
|
|
infix 8 -:
|
2012-07-19 11:51:57 +00:00
|
|
|
name -: tipe = (,) name $ Forall [] [] tipe
|
2012-05-18 03:16:16 +00:00
|
|
|
|
2012-05-12 04:27:59 +00:00
|
|
|
parens = ("("++) . (++")")
|
|
|
|
|
2012-04-19 06:32:10 +00:00
|
|
|
instance Show Type where
|
|
|
|
show t =
|
2013-03-14 08:04:51 +00:00
|
|
|
let show' t = case t of { LambdaT _ _ -> parens (show t) ; _ -> show t }
|
|
|
|
in case t of
|
|
|
|
LambdaT t1@(LambdaT _ _) t2 -> show' t1 ++ " -> " ++ show t2
|
|
|
|
LambdaT t1 t2 -> show t1 ++ " -> " ++ show t2
|
|
|
|
VarT x -> 't' : show x
|
|
|
|
ADT "List" [ADT "Char" []] -> "String"
|
|
|
|
ADT "List" [tipe] -> "[" ++ show tipe ++ "]"
|
|
|
|
ADT name cs ->
|
|
|
|
if isTupleString name
|
|
|
|
then parens . intercalate "," $ map show cs
|
|
|
|
else case cs of
|
|
|
|
[] -> name
|
|
|
|
_ -> name ++ " " ++ unwords (map show cs)
|
|
|
|
Super ts -> "{" ++ (intercalate "," . map show $ Set.toList ts) ++ "}"
|
|
|
|
EmptyRecord -> "{}"
|
|
|
|
RecordT fs t ->
|
|
|
|
start ++ intercalate ", " (concatMap fields $ Map.toList fs) ++ " }"
|
|
|
|
where field n s = n ++ " :: " ++ show s
|
|
|
|
fields (n,ss) = map (field n) ss
|
|
|
|
start = case t of
|
|
|
|
EmptyRecord -> "{ "
|
|
|
|
_ -> "{ " ++ show t ++ " | "
|
|
|
|
|
2012-07-19 11:51:57 +00:00
|
|
|
|
2012-08-09 14:38:18 +00:00
|
|
|
instance Show Scheme where
|
2012-12-25 08:39:18 +00:00
|
|
|
show (Forall [] [] t) = show t
|
|
|
|
show (Forall xs cs t) =
|
|
|
|
concat [ "Forall ", show xs
|
|
|
|
, concatMap (("\n "++) . show) cs
|
|
|
|
, "\n ", parens (show t) ]
|
2012-07-19 11:51:57 +00:00
|
|
|
|
|
|
|
isTupleString str = "Tuple" `isPrefixOf` str && all isDigit (drop 5 str)
|