Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Yesod route containing a `Maybe a` argument

I've been trying to use a Maybe a in a route. So far I tried

/u/#Maybe UserId
/u/#(Maybe UserId)
/u/#Maybe-UserId

and

/u/#MaybeUserId

where

type MaybeUserId = Maybe UserId

But without much success.

Strangely enough, #Maybe-UserId compiles fine with an handler using Maybe UserId but, it's not able to find a match even with the new PathPiece instance below.

instance (PathPiece a) => PathPiece (Maybe a) where
    fromPathPiece s = case s of
        "Nothing" -> Nothing
        _ -> Just $ fromPathPiece s
    toPathPiece m = case m of
        Just s -> toPathPiece s
        _ -> "Nothing"

What am I missing to create Maybe routes and not having to declare an a type and instance for each and every Maybe a that I want to use?

edit: The instance works fine when using anything other than Ǹothing for some reason.

edit2: "Nothing" -> Nothing actualy indicates that the PathPiece failed parsing, which is not the desired outcome. "Nothing" -> Just Nothing does the right thing.

like image 309
gxtaillon Avatar asked Mar 20 '23 06:03

gxtaillon


2 Answers

A route with an empty parameter (ending with a slash) reverts to a route ending with the previous path piece, so "/u/" will never match "/u/#MaybeUserId"

So there are two different routes in your optional UserId proposition:

/u  UserNoIdR  GET

/u/#UserId  UserWithIdR GET

Update:

You may serve them both from a common handler, if you want:

getUserNoIdR = getUserMaybe Nothing

getUserWithIdR userId = getUserMaybe (Just userId)
like image 74
Gabriel Riba Avatar answered Mar 28 '23 16:03

Gabriel Riba


For everyone coming from Google, the following is indeed the correct route syntax:

/user/#Maybe-UserId    UserR GET

for the handler:

getUserR :: Maybe UserId -> Handler Html

Which you can access with the URLs

/user/Nothing  -> Nothing
/user/Just%207 -> Just 7
like image 32
mb21 Avatar answered Mar 28 '23 18:03

mb21