1

I'm using Lucid to generate code for a static site, writing code in the HtmlT (Reader MyEnv) monad to transparently pass around some configuration stored in MyEnv.

The framework I'm using encapsulates the transformation from Html () to file output, so I'd like to write a function to transform HtmlT (Reader MyEnv) () to Html (); something like:

withEnv :: MyEnv -> HtmlT (Reader MyEnv) () -> Html ()

But I haven't yet come up with a simple way to implement this. Am I missing something fundamental, or is there a workaround?

mcwitt
  • 1,054
  • 1
  • 11
  • 10
  • You haven't come up with a simple way, but what way have you come up with? Show us the effort you have made and we can go from there. –  May 15 '20 at 18:06
  • 2
    `HtmlT (ReadMyEnv)` is not a complete type, your signature is incorrect. If you wanted `HtmlT ((->) MyEnv) a -> (->) MyEnv (Html a)`, that's called [`commuteHtmlT`](https://hackage.haskell.org/package/lucid-2.9.12/docs/Lucid-Base.html#v:commuteHtmlT). – HTNW May 15 '20 at 18:07
  • @MichaelLitchard good call, I honestly was pretty stuck and didn't think I had much worth posting. Will consider in the future though. – mcwitt May 15 '20 at 18:12
  • @HTNW Thanks, I fixed the signature. commuteHtmlT looks like exactly what I was looking for! Frustrating that I didn't find that after a good deal of searching – mcwitt May 15 '20 at 18:15
  • 1
    I guess the fundamental concept I had been missing is the commute*T family of functions. – mcwitt May 15 '20 at 18:25
  • @HTNW I think it's worth writing that as an answer. – Joseph Sible-Reinstate Monica May 15 '20 at 21:42

1 Answers1

1

You can use commuteHtmlT:

commuteHtmlT :: HtmlT (Reader MyEnv) a -> Reader MyEnd (Html a)
runReader :: Reader a r -> a -> r

withEnv :: MyEnv -> HtmlT (Reader MyEnv) a -> Html a
withEnv e = ($ e) . runReader . commuteHtmlT
HTNW
  • 27,182
  • 1
  • 32
  • 60