Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell中的管道和回调_Haskell - Fatal编程技术网

Haskell中的管道和回调

Haskell中的管道和回调,haskell,Haskell,我正在用portaudio处理一些音频。只要有音频数据需要处理,haskell FFI绑定就会调用用户定义的回调。这个回调应该处理得非常快,理想情况下不需要I/O。我想保存音频输入并快速返回,因为我的应用程序不需要实时响应音频(现在我只是将音频数据保存到文件中;稍后我将构建一个简单的语音识别系统) 我喜欢管道的想法,并认为我可以使用该库。问题是我不知道如何创建一个生产者,它返回通过回调传入的数据 我如何处理我的用例 以下是我目前正在处理的内容,以防有所帮助(数据mvar目前不起作用,但我不喜欢

我正在用portaudio处理一些音频。只要有音频数据需要处理,haskell FFI绑定就会调用用户定义的回调。这个回调应该处理得非常快,理想情况下不需要I/O。我想保存音频输入并快速返回,因为我的应用程序不需要实时响应音频(现在我只是将音频数据保存到文件中;稍后我将构建一个简单的语音识别系统)

我喜欢
管道
的想法,并认为我可以使用该库。问题是我不知道如何创建一个
生产者
,它返回通过回调传入的数据

我如何处理我的用例


以下是我目前正在处理的内容,以防有所帮助(数据mvar目前不起作用,但我不喜欢将所有数据存储在序列中……我宁愿按原样处理,而不是只在最后处理):

{-#语言灵活实例,MultiparamTypeClass}
模块主要在哪里
导入编解码器.Wav
导入Sound.PortAudio
导入Sound.PortAudio.Base
导入Sound.PortAudio.Buffer
进口外国货
进口外国货
导入外国C.C.类型
进口国外。可储存
将限定数据导入。StorableVector作为SV
将限定的Data.StorableVector.Base导入为SVB
导入控件.Exception.Base(评估)
导入数据.Int
导入数据。顺序如下
导入控制。并发
实例缓冲区SV.Vector a,其中
fromForeignPtr fp=返回。SVB.fromForeignPtr fp
toForeignPtr=返回。(\(a,b,c)->(a,c))。SVB.toForeignPtr
--|将缓冲区回调包装为通用流回调类型。
buffCBtoRawCB':(流格式输入、流格式输出、缓冲区a输入、缓冲区b输出)=>
BuffStreamCallback输入输出a b->StreamCallback输入输出
buffCBtoRawCB'func=\a b c d e->do
fpA SV.Vector Int32->SV.Vector Int32->IO StreamResult
回调seqmvar=\timeinfo flags numsamples input output->do
putStrLn$“timeinfo:++show timeinfo++”标志是在带有“++show numsamples++”样本的回调中的“++show flags++”
打印输入
--将数据写入输出
--mapM(uncurry$pokeElemOff输出)$zip(map from integral[0..(numsamples-1)]数据
--打印“写入的数据”
输入‘返回$s序列。|>输入’)
案例标志
[]->如果unPaTime(outputBufferDacTime timeinfo)>0.2,则返回$if,然后完成,否则继续
_->返回完成
doneMVar=do
putStrLn“全部完成
putMVar doneMVar True
返回()
main=do
设采样率=16000

Nothing最简单的解决方案是使用
MVar
s在回调和
Producer
之间进行通信。以下是方法:

import Control.Proxy
import Control.Concurrent.MVar

fromMVar :: (Proxy p) => MVar (Maybe a) -> () -> Producer p a IO ()
fromMVar mvar () = runIdentityP loop where
    loop = do
        ma <- lift $ takeMVar mvar
        case ma of
            Nothing -> return ()
            Just a  -> do
                respond a
                loop

编辑:现在提供了这个特性,它甚至有一个具体的解释如何使用它来从回调中获取数据。< /P>你能给出一些从没有调用管道的调用中获取数据的示例代码吗?也许考虑使用通道而不是使用代码> MVar < /COD>序列。对于这类生产者-消费者问题,它们非常有效。如果您想在消费者还没有来得及获取最新值时交错执行,而不是阻塞

putMVar
,则可以轻松使用
Chan
。代价是你可能会使用更多的内存。没错。这取决于您是否希望回调与生产者同步。
import Control.Proxy
import Control.Concurrent.MVar

fromMVar :: (Proxy p) => MVar (Maybe a) -> () -> Producer p a IO ()
fromMVar mvar () = runIdentityP loop where
    loop = do
        ma <- lift $ takeMVar mvar
        case ma of
            Nothing -> return ()
            Just a  -> do
                respond a
                loop
>>> mvar <- newEmptyMVar :: IO (MVar (Maybe Int))
>>> forkIO $ runProxy $ fromMVar mvar >-> printD
>>> putMVar mvar (Just 1)
1
>>> putMVar mvar (Just 2)
2
>>> putMVar mvar Nothing
>>> putMVar mvar (Just 3)
>>>