Is there a way to chain functions like withCString
? By that I mean any
function that looks something like f :: Foo -> (CFoo -> IO a) -> IO a
.
For example, lets say there is a function cFunc :: CString -> CFoo -> CBar -> IO ()
Usualy, I would do something like:
haskellFunc string foo bar =
withCString string $ \ cString ->
withCFoo foo $ \ cFoo ->
withCBar bar $ \ cBar ->
cFunc cString cFoo cBar
But i would like to do something like:
haskellFunc = (withCString |.| withCFoo |.| withCBar) cFunc
with some appropriate composition operator |.|
.
I'm writing library with a lot of C bindings, and this boilerplate comes often. Am I doing something wrong?
You can use the Cont
inuation applicative for composing these a -> (b -> IO c) -> IO c
functions:
import Control.Monad.Cont
haskellFunc :: String -> Foo -> Bar -> IO ()
haskellFunc string foo bar = flip runCont id $
cFunc <$>
cont (withCString string) <*>
cont (withCFoo foo) <*>
cont (withCBar bar)
Or with a bit of extra syntax:
haskellFunc' :: String -> Foo -> Bar -> IO ()
haskellFunc' string foo bar = flip runCont id $
cFunc <<$>> withCString string <<*>> withCFoo foo <<*>> withCBar bar
where
f <<$>> x = f <$> cont x
f <<*>> x = f <*> cont x
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With