zinza-0.2: src/Zinza/Type.hs
module Zinza.Type (
Ty (..),
tyUnit,
displayTy,
) where
import qualified Data.Map as M
import Zinza.Var
-- $setup
-- >>> import Zinza
-- >>> import Data.Proxy (Proxy (..))
-- | Zinza types.
--
-- The 'selector's tell how the Haskell value can be
-- converted to primitive value. E.g.
--
-- >>> toType (Proxy :: Proxy Char)
-- TyString (Just "return")
--
-- Here, 'return' converts 'Char' to 'String'.
--
data Ty
= TyBool -- ^ boolean
| TyString (Maybe Selector) -- ^ string
| TyList (Maybe Selector) Ty -- ^ lists
| TyRecord (M.Map Var (Selector, Ty)) -- ^ records
| TyFun Ty Ty -- ^ functions
deriving (Eq, Ord, Show)
-- | A record without fields is a unit type. Think of zero-field tuple: @()@.
tyUnit :: Ty
tyUnit = TyRecord M.empty
-- | Pretty print 'Ty'.
displayTy :: Ty -> String
displayTy ty = go 0 ty "" where
go :: Int -> Ty -> ShowS
go _ TyBool = showString "Bool"
go _ (TyString _) = showString "String"
go _ (TyList _ t) = showChar '[' . go 0 t . showChar ']'
go _ (TyRecord m) = case M.toList m of
[] -> showString "{}"
((n,(_,t)) : nts) -> foldl
(\acc (n',(_,t')) -> acc . showString ", " . showPair n' t')
(showChar '{' . showPair n t)
nts
. showChar '}'
go d (TyFun a b) = showParen (d > 10) $
go 11 a . showString " -> " . go 10 b
showPair n t = showString n . showString ": " . go 0 t