{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Moo.Prelude (
self,
call,
M,
E,
D
) where
import Moo
import Data.Kind
import GHC.TypeLits
import Control.Monad.Reader
import Control.Monad.Dep.Has
type Call :: Type -> Constraint
class Call curried where
type LiftedD curried :: Type
self :: (E -> curried) -> LiftedD curried
instance Call (D r) where
type LiftedD (D r) = M r
self :: (E -> D r) -> LiftedD (D r)
self E -> D r
extractor = do
E
e <- M E
forall r (m :: * -> *). MonadReader r m => m r
ask
D r -> M r
forall x. D x -> M x
liftD (D r -> M r) -> D r -> M r
forall a b. (a -> b) -> a -> b
$ E -> D r
extractor E
e
instance Call curried' => Call (a -> curried') where
type LiftedD (a -> curried') = a -> LiftedD curried'
self :: (E -> a -> curried') -> LiftedD (a -> curried')
self E -> a -> curried'
extractor a
a =
let extractor' :: E -> curried'
extractor' = \E
e -> E -> a -> curried'
extractor E
e a
a
in (E -> curried') -> LiftedD curried'
forall curried. Call curried => (E -> curried) -> LiftedD curried
self @curried' E -> curried'
extractor'
call :: forall component curried . (Has component D E, Call curried) => (component D -> curried) -> LiftedD curried
call :: (component D -> curried) -> LiftedD curried
call component D -> curried
extractor = (E -> curried) -> LiftedD curried
forall curried. Call curried => (E -> curried) -> LiftedD curried
self (component D -> curried
extractor (component D -> curried) -> (E -> component D) -> E -> curried
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (d :: * -> *) e. Has component d e => e -> component d
forall (r_ :: (* -> *) -> *) (d :: * -> *) e.
Has r_ d e =>
e -> r_ d
dep @component)