Last active
February 25, 2019 00:18
-
-
Save benkolera/0fd7bf9a57775ab01b8a7ec83f5fb755 to your computer and use it in GitHub Desktop.
Need to figure out how to get this route to work...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- The problem is that I need to model the following routes: | |
-- * /profile/:username | |
-- * /profile/:username/favourites | |
-- | |
-- And I'm a little stuck and I'm not sure whether it is my encoding of the routes, | |
-- that I'm missing an important combinator or Obelisk just doesn't handle this yet. | |
newtype Username = Username { unUsername :: Text } deriving (Eq, Ord, Show) | |
makeWrapped ''Username | |
data FrontendRoute :: * -> * where | |
FrontendRoute_Home :: FrontendRoute () | |
FrontendRoute_Profile :: FrontendRoute (Username, Maybe (R ProfileRoute)) | |
data ProfileRoute :: * -> * where | |
ProfileRoute_Favourites :: ProfileRoute () | |
backendRouteEncoder | |
:: Encoder (Either Text) Identity (R (Sum BackendRoute (ObeliskRoute FrontendRoute))) PageName | |
backendRouteEncoder = handleEncoder (const (InL BackendRoute_Missing :/ ())) $ | |
pathComponentEncoder $ \case | |
InL backendRoute -> case backendRoute of | |
BackendRoute_Missing -> PathSegment "missing" $ unitEncoder mempty | |
InR obeliskRoute -> obeliskRouteSegment obeliskRoute $ \case | |
FrontendRoute_Home -> PathEnd $ unitEncoder mempty | |
FrontendRoute_Profile -> PathSegment "profile" $ unicorn | |
unicorn | |
:: (MonadError Text parse, check ~ parse) | |
=> Encoder check parse (Username, Maybe (R ProfileRoute)) PageName | |
unicorn = segmentParam unwrappedEncoder profileRMayEnc -- This may be nonsensical. Follow reasoning below | |
where | |
-- I know how to do these two things separately! But it doesn't feel like this is the way to go | |
-- because both encoders would encode into query params and could clash horribly | |
usernameEnc :: (Applicative check, MonadError Text parse) => Encoder check parse Username PageName | |
usernameEnc = singlePathSegmentEncoder . unwrappedEncoder | |
profileRMayEnc :: (MonadError Text check, check ~ parse) => Encoder check parse (Maybe (R ProfileRoute)) PageName | |
profileRMayEnc = maybeEncoder (unitEncoder mempty) $ pathComponentEncoder $ \case | |
ProfileRoute_Favourites -> PathEnd $ unitEncoder mempty | |
-- It feels like you want something that can peel a pathPart off and handle the rest as a sub | |
-- like the maybeEncoder, but it's a 1 or more encoder that doesn't lose the params. | |
segmentParam | |
:: MonadError Text parse | |
=> Encoder check parse a Text | |
-> Encoder check parse b PageName | |
-> Encoder check parse (a,b) PageName | |
segmentParam = undefined | |
-- But I don't know whether this makes sense or could be implemented lawfully | |
-- This kinda looks like chainEncoder, but chainEncoder doesn't feel like it | |
-- I may just missing the implication of an important instance on Encoder | |
-- * Category (Encoder check parse) | |
-- * Associative (Encoder check parse) (,) | |
-- * Monoidal (Encoder check parse) (,) | |
-- * Cat.Functor f (Encoder check parse) (Encoder check parse) | |
-- * PFunctor (,) (Encoder check parse) (Encoder check parse) | |
-- * QFunctor (,) (Encoder check parse) (Encoder check parse) | |
-- * Bifunctor (,) (Encoder check parse) (Encoder check parse) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment