{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveTraversable #-}
{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
module Knit.Effect.Docs
(
Docs
, newDoc
, toNamedDocList
, toNamedDocListWith
, toNamedDocListWithM
, NamedDoc(..)
, mapNamedDocs
, mapNamedDocsM
)
where
import qualified Data.Text as T
import qualified Polysemy as P
import Polysemy.Internal ( send )
import qualified Polysemy.Writer as P
data Docs a m r where
NewDoc :: T.Text -> a -> Docs a m ()
newDoc :: P.Member (Docs a) effs => T.Text -> a -> P.Semantic effs ()
newDoc name doc = send $ NewDoc name doc
data NamedDoc a = NamedDoc { ndName :: T.Text, ndDoc :: a } deriving (Functor, Foldable, Traversable)
toWriter
:: P.Semantic (Docs a ': effs) ()
-> P.Semantic (P.Writer [NamedDoc a] ': effs) ()
toWriter = P.reinterpret f
where
f :: Docs a m x -> P.Semantic (P.Writer [NamedDoc a] ': effs) x
f (NewDoc n d) = P.tell [NamedDoc n d]
toNamedDocList
:: P.Typeable a
=> P.Semantic (Docs a ': effs) ()
-> P.Semantic effs [NamedDoc a]
toNamedDocList = fmap fst . P.runWriter . toWriter
mapNamedDocs :: Monad m => (a -> b) -> m [NamedDoc a] -> m [NamedDoc b]
mapNamedDocs f = fmap (fmap (fmap f))
mapNamedDocsM :: Monad m => (a -> m b) -> m [NamedDoc a] -> m [NamedDoc b]
mapNamedDocsM f = (traverse (traverse f) =<<)
toNamedDocListWith
:: P.Typeable a
=> (a -> b)
-> P.Semantic (Docs a ': effs) ()
-> P.Semantic effs [NamedDoc b]
toNamedDocListWith f = mapNamedDocs f . toNamedDocList
toNamedDocListWithM
:: P.Typeable a
=> (a -> P.Semantic effs b)
-> P.Semantic (Docs a ': effs) ()
-> P.Semantic effs [NamedDoc b]
toNamedDocListWithM f = mapNamedDocsM f . toNamedDocList