1 {-# LANGUAGE AllowAmbiguousTypes #-}
2 {-# OPTIONS_GHC -Wno-orphans #-}
9 import Data.Function (const, (.))
10 import Data.Kind (Constraint, Type)
11 import Network.URI.Slug qualified as URI
12 import Symantic.Classes (
19 import Symantic.Data (Data, SomeData (..))
20 import Symantic.Reader (Reader (..))
22 -- import Control.Applicative (Applicative (..))
23 -- import Data.List qualified as List
25 import Data.Set qualified as Set
26 import Symantic.Derive
28 --deriving instance Slugable repr => Slugable (Reflector r repr)
29 --deriving instance Endable repr => Endable (Reflector r repr)
30 --deriving instance Capturable repr => Capturable (Reflector r repr)
34 -- | Syntax (final algebra) for expressing URL paths.
35 class Slugable repr where
36 -- chooseSlugs :: Set [URI.Slug] -> repr [URI.Slug]
37 -- default chooseSlugs :: FromDerived Slugable repr => Set [URI.Slug] -> repr [URI.Slug]
38 -- chooseSlugs = liftDerived . chooseSlugs
40 literalSlug :: URI.Slug -> repr ()
41 default literalSlug :: IsoFunctor repr => URI.Slug -> repr ()
42 literalSlug s = Iso (const ()) (const s) <%> chooseSlug (Set.singleton s)
44 chooseSlug :: Set URI.Slug -> repr URI.Slug
45 default chooseSlug :: FromDerived Slugable repr => Set URI.Slug -> repr URI.Slug
46 chooseSlug = liftDerived . chooseSlug
48 -- default chooseSlug :: IsoFunctor repr => Set URI.Slug -> repr URI.Slug
49 -- chooseSlug s = Iso List.head pure <%> chooseSlugs (Set.mapMonotonic pure s)
51 instance (Slugable repr, IsoFunctor repr) => Slugable (Reader r repr)
53 -- | Pattern-matchable encoding (initial algebra) of 'Slugable'.
54 data instance Data Slugable repr a where
55 LiteralSlug :: URI.Slug -> Data Slugable repr ()
56 ChooseSlug :: Set URI.Slug -> Data Slugable repr URI.Slug
58 -- ChooseSlugs :: Set [URI.Slug] -> Data Slugable repr [URI.Slug]
60 -- | Initial to final algebra.
61 instance Slugable repr => Derivable (Data Slugable repr) where
63 LiteralSlug x -> literalSlug x
64 ChooseSlug x -> chooseSlug x
66 -- ChooseSlugs x -> chooseSlugs x
68 -- | Final to initial algebra.
69 instance Slugable repr => Slugable (SomeData repr) where
70 literalSlug = SomeData . LiteralSlug
71 chooseSlug = SomeData . ChooseSlug
73 --chooseSlugs = SomeData . ChooseSlugs
75 -- | Convenient alias for an @index.html@ page.
76 index :: Slugable repr => repr ()
77 index = literalSlug "index.html"
79 -- | Convenient alias for prefixing with a 'literalSlug'.
81 ProductFunctor repr =>
86 (</>) n = (literalSlug n .>)
90 -- * Class 'Capturable'
91 class Capturable repr where
92 captureSlug :: URI.Slug -> repr URI.Slug
93 default captureSlug :: FromDerived Capturable repr => URI.Slug -> repr URI.Slug
94 captureSlug = liftDerived . captureSlug
95 instance Capturable repr => Capturable (Reader r repr)
96 data instance Data Capturable repr a where
97 CaptureSlug :: URI.Slug -> Data Capturable repr URI.Slug
98 instance Capturable repr => Derivable (Data Capturable repr) where
100 CaptureSlug n -> captureSlug n
101 instance Capturable repr => Capturable (SomeData repr) where
102 captureSlug = SomeData . CaptureSlug
104 -- * Class 'Fileable'
105 class Fileable repr where
106 type FileableConstraint repr :: Type -> Constraint
108 dynamic :: FileableConstraint repr a => repr a
111 class Endable repr where
113 default end :: FromDerived Endable repr => repr ()
114 end = liftDerived end
115 instance Endable repr => Endable (Reader r repr)