HaRe-0.6: tools/hs2isabelle/AST/IsabelleType.hs
module IsabelleType where
import Mixfix
import Char(isAlpha)
data Sort = Sort [String] | DefaultSort
tVar a = TVar a DefaultSort
data Type
= TVar String Sort
| TType String [Type]
| TCfun Type Type
| TFfun Type Type
| TCprod Type Type
| TSprod Type Type
| TSsum Type Type
tApp (TType s ts) t = TType s (ts ++ [t])
foldr1' :: (a -> a -> a) -> a -> [a] -> a
foldr1' f z [] = z
foldr1' f z xs = foldr1 f xs
tCprods = foldr1' TCprod (TType "unit" [])
tSprods = foldr1' TSprod (TType "one" [])
tSsums = foldr1' TSsum (TType "unit" [])
tFfuns ts t = foldr TFfun t ts
tCfuns ts t = foldr TCfun t ts
tList t = TType "list" [t]
type TypePattern = Type
-- Datatype declarations
data TypesDecl = TypesDecl TypePattern Type
data TypeSig = TypeSig String Type
data ConstsDecl = ConstsDecl [TypeSig]
data Strictness = Lazy | Strict
data DomainArg = DomainArg Strictness String Type
data DomainCons = DomainCons String [DomainArg]
data DomainType = DomainType TypePattern [DomainCons]
data DomainDecl = DomainDecl [DomainType]
------------------------------------------------------------
instance Show Sort where
showsPrec p DefaultSort = id
showsPrec p (Sort xs) = showString "::" . case xs of
[x] -> showString x
xs -> showBraces (showCommaSep (map showString xs))
instance Show Type where
showsPrec p x = case x of
TVar a s -> showChar '\'' . showString a . shows s
-- special case for list constructor
TType "[]" [t] -> showSquares (shows t)
-- special case for tuple constructors
TType ('(':_) ts -> showSpace . showAngles (showCommaSep (map shows ts))
TType c [] -> showTypeName c
TType c [t] -> shows t . showSpace . showTypeName c
TType c ts -> showParens (showCommaSep (map shows ts)) .
showSpace . showTypeName c
TCfun t t' -> mixfix "_ -> _" [showsPrec 1 t, showsPrec 0 t'] 0 p
TFfun t t' -> mixfix "_ => _" [showsPrec 1 t, showsPrec 0 t'] 0 p
TCprod t t' -> mixfix "_ * _" [showsPrec 21 t, showsPrec 20 t'] 20 p
TSprod t t' -> mixfix "_ ** _" [showsPrec 21 t, showsPrec 20 t'] 20 p
TSsum t t' -> mixfix "_ ++ _" [showsPrec 11 t, showsPrec 10 t'] 10 p
where showTypeName c = showString c -- ('H':c)
instance Show TypesDecl where
showsPrec p (TypesDecl lhs rhs) =
mixfix "types _ = _\n" [shows lhs, showQuotes (shows rhs)] 1000 p
instance Show TypeSig where
showsPrec _ (TypeSig name typ) = if isAlpha (head name)
then showString name . showString " :: " . showQuotes (shows typ)
else showQuotes (showString ('`':name)) . showString " :: " .
showQuotes (shows typ) . showString (" (infixl \"`" ++ name ++ "\" 90)")
instance Show ConstsDecl where
showsPrec _ (ConstsDecl sigs) =
showString "consts\n" . showAll (map (showLR " " "\n" . shows) sigs)
instance Show DomainArg where
showsPrec _ (DomainArg str name t) = case (str,name) of
(Strict, "") -> show_t
(Strict, s) -> showParens (showString s . showString "::" . show_t)
(Lazy, "") -> showParens (showString "lazy " . show_t)
(Lazy, s) -> showParens
(showString "lazy " . showString s . showString "::" . show_t)
where show_t = showQuotes (shows t)
instance Show DomainCons where
showsPrec _ (DomainCons s []) = showString s
showsPrec _ (DomainCons s args) =
showString s . showSpace . showSpaceSep (map shows args)
instance Show DomainType where
showsPrec _ (DomainType t cons) =
shows t . showString " = " . showBarSep (map shows cons)
instance Show DomainDecl where
showsPrec _ (DomainDecl ds) =
showString "domain\n" .
showSep (showString "and\n") (map (showLR " " "\n" . shows) ds)
------------------------------------------------------------
-- for testing
a' = tVar "a"
b' = tVar "b"
c' = tVar "c"
d' = tVar "d"
--a' = TVar "a" (Sort ["cpo"])
{-
domain 'a tree = Leaf (value :: "'a") | Node (children :: "'a forest")
and 'a forest = Empty | Trees (head :: "'a tree") (tail :: "'a forest")
-}
tree_forest :: DomainDecl
tree_forest = DomainDecl [tree, forest]
where
a_tree = TType "tree" [a']
a_forest = TType "forest" [a']
tree = DomainType a_tree [leaf, node]
leaf = DomainCons "Leaf" [DomainArg Lazy "value" a']
node = DomainCons "Node" [DomainArg Lazy "children" a_forest]
forest = DomainType a_forest [empty, trees]
empty = DomainCons "Empty" []
trees = DomainCons "Trees"
[DomainArg Lazy "" a_tree, DomainArg Strict "" a_forest]