jaspervdj / hakyll

A static website compiler library in Haskell
jaspervdj.be/hakyll
Other
2.68k stars 409 forks source link

Add a "RulesT" transformer and define "Rules" in terms of it. #1040

Open netogallo opened 1 month ago

netogallo commented 1 month ago

Currently, the "Rules" type has the following definition:

-- | The monad used to compose rules
newtype Rules a = Rules
    { unRules :: RWST RulesRead RuleSet RulesState IO a
    } deriving (Monad, MonadFail, Functor, Applicative)

This has the unfortunate consequence that IO must be at the bottom of the monad stack in Hakyll, preventing it from integrating with recent libraries such as RIO. Could this definition be updated to:

newtype RulesT m a = Rules
    { unRules :: RWST RulesRead RuleSet RulesState m a
    } deriving (Monad, MonadFail, Functor, Applicative)

type Rules = RulesT IO

Obviously this would require a lot of code to be updated, this issue is meant to ask if you would be open to this possibility to see if I could attempt to implement the changes.

Finally, I would favor leaving the current API as unchanged as possible and simply add new functions (like hakyllT) for users who wish to use the transformer.

Minoru commented 1 month ago

Generally I'm in favour of this, because there's really no reason to tie ourselves so tightly to IO. We're okay as long as it's somewhere in the monad stack. Also, I think we can avoid adding new functions; simply replacing ... -> IO a with MonadIO m => ... -> m a should do the trick?

But such a large change can only be green-lit by @jaspervdj.

netogallo commented 1 month ago

Good point! It is probably not necessary to add new functions. Bear in mind that even if that doesn't break Hakyll's code itself, there is the (unlikely) scenario that users of Hakyll are doing it in such a way that the IO type can no longer be inferred automatically in their code. Should not be a major problem as adding a type signature would fix it.

Lets see what @jaspervdj thinks.