如何将参数传递给外部导出函数到管道中?

4

I have a

foreign export stdcall tick :: Integer -> Float -> Float -> IO Int

在每次调用此函数时,我希望将其参数传递到来自Haskell Pipes库的一组管道中。在调用之间,我不希望管道遗忘最近10次调用的参数的最小值和最大值。我该如何做到这一点?

作为建议,您可以使用MVar来保留管道中保存的内部状态,并且从您的tick函数的签名来看,所有操作都必须在IO单子中发生。没有最小工作示例很难说。 - bheklilr
不确定您想要什么。您不会将值传递到管道中,而是从管道创建一个管道,并使用runEffect运行该管道。 - Ankur
1
我想要类似于Pipes.Network.TCP.fromSocket的东西,但不是从Socket获取数据,而是一个生产者,它从上次生产者产出以来的所有tick调用中产生数据。 - Edwin Jose Palathinkal
你的问题似乎有两个部分:如何保留最后10次调用,以及如何使用Haskell pipes库。你想做哪一个?你要使用哪个“pipes”?也许如果你告诉我们你实际想解决的问题会更好? - Paul Johnson
1个回答

1
这是“pipes-concurrency”旨在完成的众多任务之一。您需要spawn一个缓冲区,每次调用派生的tick函数时,它会将其参数放入该缓冲区中。然后,您可以使用管道流来输出该缓冲区中的所有内容。
import Control.Concurrent.Async
import Pipes
import Pipes.Concurrent
import qualified Pipes.Prelude as P

-- Your FFI tick function, which we will wrap with a derived function
ffi_tick :: Integer -> Float -> Float -> IO Int
ffi_tick _ _ _ = return 0

-- A data structure just to simplify the types
-- In theory I could have just used a tuple
data Ticker = Ticker
    { _tick  :: Integer -> Float -> Float -> IO Int
    , _input :: Input (Integer, Float, Float)
    }

-- This is in charge of buffer initialization and deriving the new
-- tick function
makeTicker :: IO Ticker
makeTicker = do
    (output, input) <- spawn Unbounded
    let tick x y z = do
            atomically $ send output (x, y, z)
            ffi_tick x y z
    return (Ticker tick input)

-- This is example code showing how you would use it    
main = do
    Ticker tick input <- makeTicker
    a <- async $ runEffect $ fromInput input >-> P.print
    tick 1 2.0 3.0
    tick 4 5.0 6.0
    tick 7 8.0 9.0
    wait a

希望您没有忽略我的tick函数是一个外部导出的stdcall的事实。它旨在从另一个进程中调用,而不是从我们的主程序内部调用。包含外部导出函数的代码将被编译成DLL。 - Edwin Jose Palathinkal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接