1 module Webc.Encoder where
3 import Control.Monad (Monad (..))
4 import Control.Monad.Trans.Reader qualified as MT
5 import Data.Either (Either (..))
6 import Data.Foldable (foldMap)
7 import Data.Function (($))
8 import Data.Monoid (Endo (..), appEndo)
9 import Data.Semigroup (Semigroup (..))
10 import Network.URI.Slug
11 import Symantic.Classes (Iso (..), IsoFunctor ((<%>)), ProductFunctor ((<.>)), SumFunctor ((<+>)))
15 -- * The 'Encoder' interpreter
17 newtype Encoder a = Encoder
18 { unEncoder :: MT.Reader a (Endo [Slug])
21 encode :: Encoder a -> a -> [Slug]
22 encode (Encoder enc) a = appEndo (MT.runReader enc a) []
24 instance IsoFunctor Encoder where
25 Iso{..} <%> Encoder x = Encoder (MT.withReader b2a x)
26 instance ProductFunctor Encoder where
27 Encoder x <.> Encoder y = Encoder $
28 MT.ReaderT $ \(a, b) ->
32 instance SumFunctor Encoder where
33 Encoder x <+> Encoder y = Encoder $
35 Left a -> return $ MT.runReader x a
36 Right b -> return $ MT.runReader y b
37 instance Repeatable Encoder where
40 return $ Endo (foldMap (encode x) as <>)
42 instance Slugable Encoder where
43 literalSlug s = Encoder $ return $ Endo (s :)
44 captureSlug _n = Encoder $ MT.ReaderT $ \s -> return $ Endo (s :)