I'm still quite new to Haskell and don't have a great grasp of monads intuitively. I'm trying to write the function below:
applyPandocFilters :: (MonadIO m, PandocMonad m) => Pandoc -> m Pandoc
applyPandocFilters = do
luaEngine <- getEngine
applyFilters
luaEngine
Environment{envReaderOptions = readerOptions, envWriterOptions = writerOptions}
[ LuaFilter "./filters/lua/filters.lua"
, CiteprocFilter
]
[]
The constraint (MonadIO m, PandocMonad m) comes from the function
applyFilters :: (PandocMonad m, MonadIO m)
=> ScriptingEngine
-> Environment
-> [Filter]
-> [String]
-> Pandoc
-> m Pandoc
which I'm partially applying with all but the last two arguments filled. The issue I'm struggling with is how to use the function getEngine :: (MonadIO m) => m ScriptingEngine inside the monadic context. The way I understand the problem is that a do block only applies to a single concrete monad at a time, and the monad which the return values of getEngine and applyFilters are in are different, which is preventing them from being sequenced in a single do block, but I had thought that since getEngine's return type was wrapped in one of the monads already expressed as a typeclass constraint on the function, I would be able to use its value in applyFilters, but I get the following error, which I haven't been able to understand.
• Could not deduce ‘MonadIO ((->) Pandoc)’
arising from a use of ‘getEngine’
from the context: (MonadIO m, PandocMonad m)
bound by the type signature for:
applyPandocFilters :: forall (m :: * -> *).
(MonadIO m, PandocMonad m) =>
Pandoc -> m Pandoc
The problem I'm ultimately trying to solve is just how to transform a Pandoc document using a lua filter called from within a haskell program, for which Pandoc provides the function applyFilters, which requires a ScriptingEngine. If there's another way to apply a filter without the use of the applyFilters function, that would work as well.
I've tried reading more about MonadIO and monad transformers, but I'm not entirely sure how I would apply them to this problem. Should I be trying to wrap the PandocMonad monad inside MonadIO so the function only a single typeclass constraint? I've tried removing the PandocMonad m constraint, which I had thought would have pushed the error down to applyFilters, where indeed an error about the lack of the PandocMonad m constraint does appear, but the original error remains as well.