On Fri, Mar 26, 2010 at 10:30 AM, Michael Snoyman <michael@snoyman.com> wrote:
I also am beginning to share a mistrust of classes; I think I went a little too overboard on them on a few previous packages (namely, convertible-text) and am now having a reaction in the opposite direction. I'm sure one day I'll find the Golden Path...
* I'd like to minimize dependencies as much as possible for the basic package. The two dependencies I've noticed are Consumer and applicative-extras. I think the type signatures would be clearer *without* those packages included, eg:fromPathSegments :: [String] -> Either ErrMsg aExcept that is not a usable type. fromPathSegments may consume, some, but not all of the path segments. Consider the type:data SiteURL = Foo Int IntfromPathSegments is going to receive the path segments:["Foo","1","2"]If you wrote a parser by hand, you would want it to look a little something like:do string "Foo"slashi <- fromPathSegmentsslashj <- fromPathSegmentseolreturn (Foo i j)The key concept here is that when you call fromPathSegments to get the first argument of Foo you need to know how many of the path segments were consumed / are remaining, so you can pass only those segments to the second fromPathSegments.So you really need a type like:fromPathSegments :: [String] -> (Either ErrMsg a, [String])which outputs the unconsumed path segments.Well, given that as a criterion, I agree with the rest of your analysis entirely. However, I think we're looking at the purpose of fromPathSegments very differently. I'm not quite certain I understand why we would want to output the unconsumed segments; if something is unconsumed, then it seems like it's an invalid URL and should fail.
In your example, if I request "/Foo/5/6/7", fromPathSegments would return (Right (Foo 5 6), ["7"]); but what is going to consume that 7 now? The use case I envisioned for something like this is:
data BlogRoutes = ...
data MySite = MyHome | MyBlog BlogRoutes
fromPathSegments ("blog":rest) = MyBlog `fmap` fromPathSegments