
On Fri, Mar 26, 2010 at 6:01 PM, Jeremy Shaw
A variation which is more obviously hierarchical in nature:
data User = User LastName FirstName data Section = Recent | TopRated data UserHomeURL = Wall Section | Profile data UserURL = ViewHome User UserHome
Which would be used to construct urls like:
/shaw/jeremy/wall/recent /snoyman/michael/profile
To expand on this slightly let's pretend you first implemented a module that supported a single user: data Section = Recent | TopRated data UserHomeURL = Wall Section | Profile And you release that as a library. Then in another app, which supports multiple users, you want to use it. So you create: data User = User LastName FirstName data UserURL = ViewHome User UserHome That seems pretty sensible. After all the half the point of this library is to be able to build reusable components. Because we are reusing a component, we can not modify the UserHome portion of the URL. But we still need some way to specify which user's home we are looking at. The above types seem sensible for that. You have similar structures in your photo blog app: -------- instance Yesod PB where resources = [$mkResources| /: GET: indexHandler /entries/$entryId: GET: entry /entries/$entryId/$filename: GET: media /feed: GET: feed ... ------ A reasonable URL type for that might be: data EntryId = ... data PhotoBlogURL = BlogHome | Entry EntryId | Media EntryId FileName | Feed Where Media has two arguments to it's constructor. You can't really factor that out, can you? You could fake it like: data PhotoBlogURL = BlogHome | Entry EntryId | Media (EntryId, FileName) | Feed But that does not really buy you anything, because when you write the Media parser, you still have to know how many segments EntryId consumes, and how many FileName consumes. perhaps entryid is: data EntryId = EntryId { year :: Int , month :: Int ,