Multiple parsers at the same time - Rib

Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.

Sridhar Ratnakumar

With the latest master, being able to use multiple parsers in the same site can be achieved using the dependent-sum library. Using code like the following in the user Main.hs:

type SomeSource (srcType :: * -> *) = Source (DSum srcType Identity)

mkSomeSource :: srcType doc -> Source doc -> SomeSource srcType
mkSomeSource t = fmap (t ==>)

data SourceType :: * -> * where
  SourceType_Markdown :: SourceType MMark
  SourceType_Entry :: SourceType E.Entry

data Target
  = Target_Index [SomeSource SourceType]
  | Target_Page (SomeSource SourceType)

data MarkdownMeta
  = MarkdownMeta
      { title :: Text
  deriving (Show, Eq, Generic, FromJSON)

main :: IO ()
main = [reldir|a|] [reldir|b|] generateSite
    -- Shake Action for generating the static site
    generateSite :: Action ()
    generateSite = do
      Rib.buildStaticFiles [[relfile|static/**|]]
      docs <-
        Rib.buildHtmlMulti [[relfile|*.md|]] M.parseIO $
          renderPage . Target_Page . mkSomeSource SourceType_Markdown
      entries <-
        Rib.buildHtmlMulti [[relfile|*/*/*.dhall|]] E.parseIO $
          renderPage . Target_Page . mkSomeSource SourceType_Entry
      Rib.buildHtml [relfile|index.html|]
        $ renderPage
        $ Target_Index
        $ mconcat
          [ mkSomeSource SourceType_Entry <$> reverse (sortOn Rib.sourcePath entries),
            mkSomeSource SourceType_Markdown <$> docs
Sridhar Ratnakumar

This examples shows how we have a static site of both MMark and Dhall sources!

Sridhar Ratnakumar

Rib used to have this SourceType type, which is what got removed in the latest PR, to allow the user some flexibility.

Sridhar Ratnakumar

So now dabbling with dependent-sum is the user's responsibility.

Sridhar Ratnakumar

(Technically you can use multiple parsers at the same without any of these machinary if your Target type had unique constructors for each parser type)