If I have the following two Kleisli arrows:
stdoutProcessA :: Kleisli Maybe String (IO String)
writeToFileA :: Kleisli Maybe (FilePath, String) (IO ())
I would like to be able to write someting like:
compile = proc src -> do
output <- stdoutProcessA -< "..."
writeToFileA -< ("...", output)
...
which of course doesn’t work, because String doesn’t match with IO String. On the other hand, it is possible to define both stdoutProcessA and writeToFileA to be of type Kleisli IO ..., but then I wouldn’t be able to compose them with arrows of type Kleisli Maybe ..., which I need for other things.
I am not very experienced with arrows yet, so I’m probably missing something obvious. How would one go about doing the above?
These arrows don’t make much sense to me:
They represent functions with result
Maybe (IO a), when you probably meantIO (Maybe a). The latter type representsIOactions which may fail, while in the former the failure or success cannot depend on theIOat all.The correct way to combine
IOandMaybeis to use theMaybeTmonad transformer, like so:If you write your other arrows as
Monad m => Kleisli (MaybeT m) a b, they should compose nicely with these ones without any lifting. Alternatively, you can useto lift your existing
Kleisli Maybearrows toKleisli (MaybeT IO)where needed.