module Zinza.Value where

import qualified Data.Map.Strict as Map

import Zinza.Errors
import Zinza.Type
import Zinza.Var

-- | Template values.
data Value
    = VBool Bool                                 -- ^ booleans
    | VString String                             -- ^ strings
    | VList [Value]                              -- ^ lists
    | VRecord (Map.Map Var Value)                  -- ^ records
    | VFun (Value -> Either RuntimeError Value)  -- ^ function

-- | Calculate 'Ty' of the 'Value'.
-- This is only an approximation, for list we look at first
-- element if it exists, otherwise we use 'unitTy'.
valueType :: Value -> Ty
valueType :: Value -> Ty
valueType (VBool Bool
_)     = Ty
TyBool
valueType (VString Var
_)   = Maybe Var -> Ty
TyString Maybe Var
forall a. Maybe a
Nothing
valueType (VList [])    = Maybe Var -> Ty -> Ty
TyList Maybe Var
forall a. Maybe a
Nothing Ty
tyUnit
valueType (VList (Value
v:[Value]
_)) = Maybe Var -> Ty -> Ty
TyList Maybe Var
forall a. Maybe a
Nothing (Value -> Ty
valueType Value
v)
valueType (VRecord Map Var Value
m)   = Map Var (Var, Ty) -> Ty
TyRecord ((Value -> (Var, Ty)) -> Map Var Value -> Map Var (Var, Ty)
forall a b. (a -> b) -> Map Var a -> Map Var b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Value
v -> (Var
"", Value -> Ty
valueType Value
v)) Map Var Value
m)
valueType (VFun Value -> Either RuntimeError Value
_)      = Ty -> Ty -> Ty
TyFun Ty
tyUnit Ty
tyUnit