graphted-0.1.0.2: src/Control/Monad/Graph.hs
{- |
Module : Control.Monad.Graph
Description : Graph indexed monads
Copyright : (c) Aaron Friel
License : BSD-3
Maintainer : Aaron Friel <mayreply@aaronfriel.com>
Stability : unstable
Portability : portable
-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}
-- For the default Apply, Then, and But instances.
{-# LANGUAGE UndecidableInstances #-}
module Control.Monad.Graph where
import Control.Graphted.Class
import Control.Applicative.Graph
-- | Graph indexed monad.
class GApplicative m => GMonad (m :: p -> * -> *) where
-- | The apply operation ('>>=') on the graph index.
--
-- Default instance: @Bind m i j = 'Combine' m i j@
type family Bind m (i :: p) (j :: p) :: p
type instance Bind m i j = Combine m i j
-- | The join operation ('Control.Monad.join') on the graph index.
--
-- Default instance: @Join m i j = 'Bind' m i j@
type family Join m (i :: p) (j :: p) :: p
type instance Join m i j = Bind m i j
-- | Sequentially compose two actions, with the second dependent on the first.
gbind :: Inv m i j => m i a -> (a -> m j b) -> m (Bind m i j) b
-- | Remove one level of nested structure.
--
-- Default implementation requires the default instance of 'Join'.
{-# INLINE gjoin #-}
gjoin :: (Inv m i j) => m i (m j b) -> m (Join m i j) b
default gjoin :: (Bind m i j ~ Join m i j, Inv m i j) => m i (m j b) -> m (Join m i j) b
gjoin x = x `gbind` id