【问题标题】:Should IO run inline during propagation?IO 是否应该在传播期间内联运行?
【发布时间】:2019-05-07 23:53:24
【问题描述】:

我正在尝试在 Idris 中编写 FRP 库。该库设计为在单线程环境中运行。未来实现MonadAlign。我想用这些简化的类型签名来实现函数:

createFutureResolveLater : (Future a, a -> IO ()) -- later time

createFutureResolveNow : a -> IO (Future a) -- current time

pure : a -> Future a -- before everything

align : Future a -> Future a -> Future (These a b) -- min of two times

join : Future (Future a)) -> Future a -- max of two times

exeEvent : Future (IO a) -> IO (Future a) -- ??

simultaneous : Future a -> Future b -> Future Bool -- min of two times

subFuture : Future a -> (a -> IO ()) -> IO ()

在我看来很明显

simultaneous a a, simultaneous a (fmap f a), etc.

应该是一个解析为真的未来。

do
    oe <- exeEvent ie
    let s = simultaneous oe ie
    ...

应该解析为真吗?

在反应香蕉中,s 是假的。见http://hackage.haskell.org/package/reactive-banana-1.2.1.0/docs/Reactive-Banana-Frameworks.html中的mapEventIO

在反射中,s 也很可能是错误的。请参阅https://daig.github.io/reflex/Reflex-PerformEvent-Class.html中的 performEvent

为什么这些库作者选择 s 为假?

【问题讨论】:

    标签: haskell idris frp


    【解决方案1】:

    试图弄清楚你在问什么。我想您想知道如何解释需要时间的 IO 操作,不是吗?因为如果IO 动作是即时的,这将不是问题。虽然对我来说还有一个问题,IO 操作会阻塞直到未来发生还是异步调度?

    如果这是一个非阻塞调用,我会说它应该等到IO 操作完成。 (我也将其称为schedFuture 或其他名称以明确它不会阻塞。)否则您可能会遇到Future 的情况已经过去,但该值仍然不可用,这可能会搞砸合并事件等函数的逻辑。

    如果这是一个阻塞调用,我会改为提供

    waitFuture :: Future a -> IO a
    

    让用户处理剩下的事情(例如,如果他们想保留时间,他们可以在原始未来使用fmap (const x),如果他们想要在操作完成时使用now :: IO (Future ()),等等)。如果你能为它们想出好名字,那么为它们提供组合器可能是值得的,否则它们很容易,我只会弃用。

    我还发现,在制作这样的系统时,它有助于区分“道德瞬时”IO 动作和可能阻止的动作。我想这与javascript在异步和常规堆栈调用之间的区别是平行的。像这样的模糊问题很多,对应的明显答案往往依赖于这种区分。

    【讨论】:

    • 库中的所有内容都是单线程异步的,带有回调并且没有阻塞。
    • 我看了你的回答几次。我相信您是说它们应该同时发生,对吗?
    • 为什么 reflex 和 reactive-banana 似乎认为它们不应该同时出现?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-13
    • 2021-03-14
    • 2012-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多