[Haskell-cafe] best practice for lifting of IO and could lifting be automated?
Dimitri DeFigueiredo
defigueiredo at ucdavis.edu
Fri Oct 23 19:39:32 UTC 2015
Hello All,
I have recently encountered 2 situations where I needed an IO action,
but only had a monad stack with IO at the bottom.
The two examples were:
1. from Control.Concurrent.Async
withAsync :: IO a -> (Async a -> IO b) -> IO b
2. from Network.WebSockets
runClient :: String -- ^ Host
-> Int -- ^ Port
-> String -- ^ Path
-> (Connection -> IO a) -- ^ Client application
-> IO a
I need to pass a function that returns an IO action to both these functions.
I think my life would be easier if the function signatures were:
1. withAsync :: MonadIO mIO => mIO a -> (Async a -> mIO b) -> mIO b
2. from Network.WebSockets
runClient :: MonadIO mIO =>
-> String -- ^ Host
-> Int -- ^ Port
-> String -- ^ Path
-> (Connection -> mIO a) -- ^ Client application
-> mIO a
There are many other examples, a notable one are the functions in
Control.Exception also always expect an IO action.
I know we have libraries to solve this problem, such as lifted-async,
lifted-base and the functionality in Control.Monad.Trans.Control.
But what are the best practices for writing code that uses Monadic
actions? Should I always generalize my type signatures or just expect
others to use the libraries when they need to?
Also, to some extent it seems trivial to re-write a library like async
with the generalized signatures I need. I would just need to apply
'lift' everywhere. Couldn't the compiler do this for me? ;-)
Thanks,
Dimitri
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20151023/1dcea57d/attachment.html>
More information about the Haskell-Cafe
mailing list