1 {-# LANGUAGE DeriveFunctor #-}
2 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
3 {-# OPTIONS_GHC -fno-warn-orphans #-}
5 module Webc.Generator where
7 import Control.Applicative (Applicative (..), liftA2)
8 import Data.Either (Either (..))
9 import Data.Eq (Eq (..))
10 import Data.Function (($), (.))
11 import Data.Functor (Functor (..), (<$>))
12 import Data.Ord (Ord (..))
13 import Data.Semigroup (Semigroup (..))
14 import Network.URI.Slug as URI
15 import Symantic.Classes (Iso (..), IsoFunctor (..), ProductFunctor (..), SumFunctor ((<+>)))
16 import Text.Show (Show (..))
20 -- * The 'Generator' interpreter
22 -- | This is a very basic generator.
23 newtype Generator a = Generator
24 { unGenerator :: [Gen a]
26 deriving (Functor, Show)
28 instance Applicative Generator where
29 pure = Generator . pure . pure
30 Generator f <*> Generator x = Generator ((<*>) <$> f <*> x)
32 generate :: Generator a -> [Gen a]
33 generate = unGenerator
36 data Gen a = Gen {genSlugs :: [Slug], genValue :: a}
37 deriving (Eq, Ord, Show, Functor)
38 instance Applicative Gen where
40 f <*> x = Gen (genSlugs f <> genSlugs x) (genValue f (genValue x))
42 instance IsoFunctor Generator where
43 (<%>) Iso{..} = (a2b <$>)
44 instance ProductFunctor Generator where
48 instance SumFunctor Generator where
51 unGenerator (Left <$> x)
52 <> unGenerator (Right <$> y)
53 instance Repeatable Generator where
56 ((\Gen{} -> Gen [] []) <$> x)
57 <> ((\(Gen s a) -> Gen s [a]) <$> x)
58 <> ((\(Gen s a) -> Gen (s <> s) [a, a]) <$> x)
61 ((\(Gen s a) -> Gen s [a]) <$> x)
62 <> ((\(Gen s a) -> Gen (s <> s) [a, a]) <$> x)
63 instance Slugable Generator where
64 literalSlug s = Generator [Gen [s] ()]
65 captureSlug n = Generator [Gen [n] n]