{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DefaultSignatures #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -- | Expression for 'Functor'. module Language.Symantic.Expr.Functor where import Data.Proxy (Proxy(..)) import Data.Type.Equality ((:~:)(Refl)) import Prelude hiding (fmap) import qualified Data.Function as Fun import Language.Symantic.Type import Language.Symantic.Trans.Common import Language.Symantic.Expr.Root import Language.Symantic.Expr.Error import Language.Symantic.Expr.From import Language.Symantic.Expr.Lambda -- * Class 'Sym_Functor' -- | Symantic. class Sym_Lambda repr => Sym_Functor repr where fmap :: Functor f => repr ((->) a b) -> repr (f a) -> repr (f b) default fmap :: (Trans t repr, Functor f) => t repr ((->) a b) -> t repr (f a) -> t repr (f b) fmap = trans_map2 fmap (<$) :: Functor f => repr a -> repr (f b) -> repr (f a) (<$) a = fmap (lam (Fun.const a)) infixl 4 <$ -- | 'fmap' alias. (<$>) :: (Sym_Functor repr, Functor f) => repr ((->) a b) -> repr (f a) -> repr (f b) (<$>) = fmap infixl 4 <$> -- * Type 'Expr_Functor' -- | Expression. data Expr_Functor (root:: *) type instance Root_of_Expr (Expr_Functor root) = root type instance Type_of_Expr (Expr_Functor root) = No_Type type instance Sym_of_Expr (Expr_Functor root) repr = (Sym_Functor repr) type instance Error_of_Expr ast (Expr_Functor root) = No_Error_Expr -- | Parse 'fmap'. fmap_from :: forall root ty ast hs ret. ( ty ~ Type_Root_of_Expr (Expr_Functor root) , Eq_Type ty , Expr_from ast root , Lift_Type Type_Fun (Type_of_Expr root) , Unlift_Type Type_Fun (Type_of_Expr root) , Unlift_Type1 (Type_of_Expr root) , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast) (Error_of_Expr ast root) , Root_of_Expr root ~ root , Constraint_Type1 Functor ty ) => ast -> ast -> Expr_From ast (Expr_Functor root) hs ret fmap_from ast_g ast_fa ex ast ctx k = -- NOTE: fmap :: Functor f => (a -> b) -> f a -> f b expr_from (Proxy::Proxy root) ast_g ctx $ \(ty_g::ty h_g) (Forall_Repr_with_Context g) -> expr_from (Proxy::Proxy root) ast_fa ctx $ \(ty_fa::ty h_fa) (Forall_Repr_with_Context fa) -> check_type_fun ex ast ty_g $ \(Type_Type2 Proxy ty_g_a ty_g_b :: Type_Fun ty h_g) -> check_type1 ex ast ty_fa $ \(Type_Type1 f ty_fa_a, Lift_Type1 f_lift) -> check_constraint_type1 ex (Proxy::Proxy Functor) ast ty_fa $ \Dict -> check_eq_type ex ast ty_g_a ty_fa_a $ \Refl -> k (Type_Root $ f_lift $ Type_Type1 f ty_g_b) $ Forall_Repr_with_Context $ \c -> fmap (g c) (fa c)