{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} module Language.LOL.Symantic.Type.Maybe where import Data.Maybe (isJust) import Data.Type.Equality ((:~:)(Refl)) import Data.Proxy import Language.LOL.Symantic.AST import Language.LOL.Symantic.Type.Common import Language.LOL.Symantic.Type.Fun import Language.LOL.Symantic.Type.Bool import Language.LOL.Symantic.Type.Var -- * Type 'Type_Maybe' -- | The 'Maybe' type. data Type_Maybe root h where Type_Maybe :: root h_a -> Type_Maybe root (Maybe h_a) type instance Root_of_Type (Type_Maybe root) = root type instance Error_of_Type ast (Type_Maybe root) = () instance -- Type_Eq Type_Eq root => Type_Eq (Type_Maybe root) where type_eq (Type_Maybe a1) (Type_Maybe a2) | Just Refl <- a1 `type_eq` a2 = Just Refl type_eq _ _ = Nothing instance -- Eq Type_Eq root => Eq (Type_Maybe root h) where x == y = isJust $ type_eq x y instance -- Type_from AST ( Type_Eq root , Type_from AST root , Type_Root_Lift Type_Maybe root , Error_Type_Lift (Error_Type AST) (Error_of_Type AST root) , Error_Type_Unlift (Error_Type AST) (Error_of_Type AST root) , Root_of_Type root ~ root , Implicit_HBool (Is_Last_Type (Type_Maybe root) root) ) => Type_from AST (Type_Maybe root) where type_from px_ty ast k = case ast of AST "Maybe" asts -> case asts of [ast_a] -> type_from (Proxy::Proxy root) ast_a $ \(ty_a::root h_a) -> k (type_root_lift $ Type_Maybe ty_a :: root (Maybe h_a)) _ -> Left $ error_type_lift $ Error_Type_Wrong_number_of_arguments ast 1 _ -> Left $ error_type_unsupported px_ty ast instance -- String_from_Type String_from_Type root => String_from_Type (Type_Maybe root) where string_from_type (Type_Maybe a) = "Maybe (" ++ string_from_type a ++ ")" instance -- Show String_from_Type root => Show (Type_Maybe root h) where show = string_from_type -- | Convenient alias to include a 'Type_Maybe' within a type. type_maybe :: Type_Root_Lift Type_Maybe root => root h_a -> root (Maybe h_a) type_maybe a = type_root_lift (Type_Maybe a) -- * Type 'Type_Fun_Bool_Maybe' -- | Convenient alias. type Type_Fun_Bool_Maybe lam = Type_Root (Type_Alt Type_Var (Type_Alt (Type_Fun lam) (Type_Alt Type_Bool Type_Maybe)))