[WebRoutesDemo: move discussion on type families to the end. Jeremy Shaw **20110719185810 Ignore-this: 174baf1ba58c391a4f149da974297828 ] hunk ./WebRoutesDemo.lhs 162 -

If you are not familiar with type families and type functions, the URL m in that type signature might look a bit funny. But it is really very simple.

- -

The showURL function leverages the ShowURL class:

- -
-#ifdef HsColour -> class ShowURL m where -> type URL m -> showURLParams :: (URL m) -> [(String, String)] -> m String -#endif -
- -

And here is the RouteT instance for ShowURL:

- -
-#ifdef HsColour -> instance (Monad m) => ShowURL (RouteT url m) where -> type URL (RouteT url m) = url -> showURLParams url params = -> do showF <- askRouteT -> return (showF url params) -#endif -
- -

Here URL is a type function that is applied to a type and gives us another type. For example, writing URL (RouteT Sitemap (ServerPartT IO)) gives us the type Sitemap. We can use the type function any place we would normally use a type.

- -

In our example we had:

- -
-#ifdef HsColour -> homeURL <- showURL Home -#endif -
- -

So there, showURL is going to have the type:

- -
-#ifdef HsColour -> showURL :: URL (RouteT Sitemap (ServerPartT IO)) -> RouteT Sitemap (ServerPartT IO) String -#endif -
- -

which can be simplified to:

- -
-#ifdef HsColour -> showURL :: Sitemap -> RouteT Sitemap (ServerPartT IO) String -#endif -
- -

So, we see that the url type we pass to showURL is dictated by the monad we are currently in. This ensures that we only call showURL on values of the right type.

- -

While ShowURL is generally used with the RouteT type -- it is not actually a requirement. You can implement ShowURL for any monad of your choosing.

- +

URL m is a type-function that calculates the url type based on the monad we are currently in. For RouteT url m a, URL m is going to be whatever url is. In this example, url is Sitemap. If you are not familiar with type families and type functions, see this section.

hunk ./WebRoutesDemo.lhs 304 + +

Web Routes + Type Families

+ +

showURL has the type:

+ +
+#ifdef HsColour +> showURL :: ShowURL m => URL m -> m String +#endif +
+ +

If you are not familiar with type families and type functions, the URL m in that type signature might look a bit funny. But it is really very simple.

+ +

The showURL function leverages the ShowURL class:

+ +
+#ifdef HsColour +> class ShowURL m where +> type URL m +> showURLParams :: (URL m) -> [(String, String)] -> m String +#endif +
+ +

And here is the RouteT instance for ShowURL:

+ +
+#ifdef HsColour +> instance (Monad m) => ShowURL (RouteT url m) where +> type URL (RouteT url m) = url +> showURLParams url params = +> do showF <- askRouteT +> return (showF url params) +#endif +
+ +

Here URL is a type function that is applied to a type and gives us another type. For example, writing URL (RouteT Sitemap (ServerPartT IO)) gives us the type Sitemap. We can use the type function any place we would normally use a type.

+ +

In our example we had:

+ +
+#ifdef HsColour +> homeURL <- showURL Home +#endif +
+ +

So there, showURL is going to have the type:

+ +
+#ifdef HsColour +> showURL :: URL (RouteT Sitemap (ServerPartT IO)) -> RouteT Sitemap (ServerPartT IO) String +#endif +
+ +

which can be simplified to:

+ +
+#ifdef HsColour +> showURL :: Sitemap -> RouteT Sitemap (ServerPartT IO) String +#endif +
+ +

So, we see that the url type we pass to showURL is dictated by the monad we are currently in. This ensures that we only call showURL on values of the right type.

+ +

While ShowURL is generally used with the RouteT type -- it is not actually a requirement. You can implement ShowURL for any monad of your choosing.

+