有没有像使用CString一样链接函数的方法? [英] Is there a way to chain functions like withCString?

查看:152
本文介绍了有没有像使用CString一样链接函数的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法像 with CString 那样链接函数?我的意思是任何
函数看起来像 f :: Foo - > (CFoo→IOa)→> IO a



例如,假设有一个函数 cFunc :: CString - > CFoo - > CBar - > IO()



Usualy,我会这样做:

  haskellFunc string foo bar = 
withCString string $ \ cString - >
withCFoo foo $ \ cFoo - >
withCBar bar $ \ cBar - >
cFunc cString cFoo cBar

但是我想要这样做:

  haskellFunc =(withCString |。| withCFoo |。| withCBar)cFunc 

与一些适当的组合运算符 |。|



我正在写一个带有很多C绑定的库,而且这个样板经常是
。我做错了什么?

package / mtl-2.2.1 / docs / Control-Monad-Cont.html> Cont inuation applicative 来编写这些 a - > (b→IOc)→> IO c 函数:

  import Control.Monad.Cont 

haskellFunc :: String - > Foo - >酒吧 - > IO()
haskellFunc字符串foo bar =翻转runCont id $
cFunc< $>
cont(withCString string)< *>
cont(with CFoo foo)*<
cont(withCBar bar)

或者添加一些额外的语法:

  haskellFunc':: String  - > Foo  - >酒吧 - > IO()
haskellFunc'string foo bar = flip runCont id $
cFunc<<>>> withCString string<<>> withCFoo foo<<>> withCBar bar
where
f<< $>> x = f< $> cont x
f *<>> x = f *续x


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 Continuation 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

这篇关于有没有像使用CString一样链接函数的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆