Starting design for ReflexFRP.org

Filed under: programming

I’m continuing to practice using Reflex for web design, and this weekend I was starting to put together reflexfrp.org website. For now I’m working on a prototype that includes a brief description and some links.

Instead of hand writing each element, I’m organizing the links in a data structure (a list of tuples), and then creating the anchor tag on the fly. It’s less obvious to do since I’m not too familiar with the elAttr function or even with the list iteration functions in Haskell. Regardless, I pushed onwards.

First, it’s important to think about where to save the link information, and in a manner that would later be easy to update. In Python web development, I’d most likely be using Django or Flask, and with those frameworks you can pass in data to the template with dictionaries. I’m not sure if Haskell has a similar hashtable like data structure, I couldn’t find it so I figured a list of 2 element tuples would suffice.

Here’s how the list of tuples look like:

  let links = [ ("hackage", "https://hackage.haskell.org/package/reflex")
              , ("twitter", "http://twitter.com")
              , ("github", "http://github.com/reflex-frp")
              , ("reddit", "http://reddit.com/r/reflexfrp")
              , ("irc.freenode.net #reflex-frp", "http://webchat.freenode.net/?channels=%23reflex-frp&uio=d4")
              ]

For each tuple, I have a pair that’s basically the channel name and the handle url, these are the key pieces of information I need to build the links. Notice how the last sentence started with for each because that’s the action we’d like our code to follow in reading the links!

  -- Create a list of links from a list of tuples
  forM_ links  \pair -> do
    elAttr "a" ("href" =: (snd pair))  text (fst pair)
    el "br"  return ()

See how the line beginning with elAttr takes the first and second elements? While this is a nice way to write it I still wish for an even more readable solution. But anyhow it works and now I can think about providing a classname and then using that for styling rather than relying on the last line to break the text into multiples lines on the page.

List iteration

At first I was looking into map, which is a function that turns a function on elements into a function on lists. But that didn’t give me the return type that I wanted. It gave me a list, but then I still needed to somehow create the elements for the webpage.

Back to the drawing board and stumbing upon this stackoverflow answer that reminded me about forM_

I forgotten that I used this last year to generate a list of dropdown menus for another prototype. This function doesn’t come in the Prelude module. To figure out which package to import, I searched for forM_ on hoogle and picked Control.Monad. That it was the right choice was confirmed by browsing the Typeclassopedia.

import Control.Monad

And now for the type signature:

Control.Monad> :t forM_
forM_ :: (Monad m, Foldable t) => t a -> (a -> m b) -> m ()