为什么有些threepenny-gui FRP组合器在MonadIO monad上运行而不是纯粹?

mig*_*rao 7 haskell frp reactive-banana threepenny-gui

首先是一个免责声明,我可能完全误解了三便器的工作方式,因为我对Haskell的知识不那么先进,所以我的断言就是一粒盐.:-)

在我看来,一些组合器不是纯粹的,例如

stepper :: MonadIO m => a -> Event a -> m (Behavior a)
Run Code Online (Sandbox Code Playgroud)

步进器是否必然在某种类型的IO monad上运行(因此它不是纯粹的),或者我在这里误解了什么?第二个问题,如果那些组合器确实不合适,那为什么呢?对我来说,这使得构建事件图的代码比反应性香蕉更好,因为必须使用IO monad而不是纯粹的普通函数.代码似乎变得比在反应性香蕉中变得更复杂.

更可怕的是,valueChange似乎是纯粹的类型

valueChange :: Element -> Event String
Run Code Online (Sandbox Code Playgroud)

但它实际上是在内部使用unsafeMapIO,它实际上是在做隐藏的IO吗?同样,我可能会误解某些东西,但这不是Haskell中最严重的罪吗?这也令人困惑,我无法从类型中看出回叫注册是如何发生的......这在我之前从未发生在Haskell中......是否这样做是为了让用户不得不处理Frameworks monad?

Tom*_*lis 5

我不是一个三便携式用户,但我可以通过阅读代码向您提供一些有关您问题的信息.

首先考虑stepper:似乎内部的threpenny-gui使用IORef来跟踪累积的参数.这就是为什么stepper要求MonadIO.不过,我不认为这需要IO以建立您的活动图,它只是意味着它必须运行在IO.这不应该导致您作为API用户的任何尴尬.如果您认为确实如此,请发布更具体的问题.

其次是关于valueChange在不安全功能方面实现:是的,这在Haskell库中很常见.Haskell库作者在知道使用它们的方式对所有可能的执行路径实际上是安全的时,通常会使用不安全的函数,但是不可能向类型系统证明这一点.换句话说,图书馆作者以安全的方式使用不安全的操作,这样你就不必!