{-# LANGUAGE ScopedTypeVariables #-}
module Zinza.Class (
Zinza (..),
) where
import Data.Foldable (toList)
import Data.Proxy (Proxy (..))
import qualified Data.List.NonEmpty as NE
import qualified Data.Map.Lazy as Map
import qualified Data.Set as Set
import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import Zinza.Type
import Zinza.Value
class Zinza a where
toType :: Proxy a -> Ty
toTypeList :: Proxy a -> Ty
toTypeList = TyList Nothing . toType
toValue :: a -> Value
toValueList :: [a] -> Value
toValueList = VList . map toValue
instance Zinza () where
toType _ = tyUnit
toValue _ = VRecord mempty
instance Zinza Bool where
toType _ = TyBool
toValue = VBool
instance Zinza Char where
toType _ = TyString (Just "return")
toTypeList _ = TyString Nothing
toValue = VString . return
toValueList = VString
instance Zinza a => Zinza [a] where
toType _ = toTypeList (Proxy :: Proxy a)
toValue = toValueList
instance (Zinza a, Zinza b) => Zinza (a, b) where
toType _ = TyRecord $ Map.fromList
[ ("fst", ("fst", toType (Proxy :: Proxy a)))
, ("snd", ("snd", toType (Proxy :: Proxy b)))
]
toValue (a, b) = VRecord $ Map.fromList
[ ("fst", toValue a)
, ("snd", toValue b)
]
instance Zinza a => Zinza (NE.NonEmpty a) where
toType _ = TyList Nothing (toType (Proxy :: Proxy a))
toValue = VList . map toValue . toList
instance Zinza a => Zinza (Set.Set a) where
toType _ = TyList Nothing (toType (Proxy :: Proxy a))
toValue = VList . map toValue . toList
instance (Zinza k, Zinza v) => Zinza (Map.Map k v) where
toType _ = TyList (Just "Map.toList") $ TyRecord $ Map.fromList
[ ("key", ("fst", toType (Proxy :: Proxy k)))
, ("val", ("snd", toType (Proxy :: Proxy v)))
]
toValue m = VList
[ VRecord $ Map.fromList
[ ("key", toValue k)
, ("val", toValue v)
]
| (k, v) <- Map.toList m
]
instance Zinza T.Text where
toType _ = TyString (Just "T.unpack")
toValue = VString . T.unpack
instance Zinza LT.Text where
toType _ = TyString (Just "LT.unpack")
toValue = VString . LT.unpack