我在haskell中编写了一个函数,它需要一些参数,如Word32,String(忽略currying)并输出Io Word32。现在,这是一个 功能 真正意义上的: 对于相同的输入,输出将始终相同.没有副作用。该函数返回IO Word32而不是Word32的原因是该函数在循环中多次更新许多32位线性反馈移位寄存器(lfsr)和其他寄存器,以便计算最终的Word32输出。

我的问题是这样的:鉴于此功能 有效无副作用, ,是否有可能隐藏函数实现内部的那些寄存器更新,以便函数返回Word32而不是IO Word32?如果是这样,如何?

有帮助吗?

解决方案

是的!Haskell可以做到这一点。

圣莫纳德

如果你实际上使用可变状态(寄存器),这是完全隐藏的观察者在函数之外,那么你在 圣莫纳德, ,仅用于记忆效果的monad。你通过 runST, ,并且当您退出函数时,所有效果都保证不可见。

它正是处理本地可变状态的正确计算环境。

纯功能状态:国家莫纳德

但是,如果您实际上并没有改变寄存器或单元格,而是多次更新纯函数值,则可以使用更简单的环境: 国家莫纳德.这不允许可变状态,但给出了局部状态的错觉。

IO,和unsafePerformIO

最后,如果你有本地的,可变的效果,比如在 ST monad,但是由于某种原因,您将需要对该状态进行IO操作(例如通过FFI调用),您可以模拟 ST monad,具有几乎一样多的安全性,通过使用 unsafePerformIO, ,而不是 runST, ,来引入本地IO环境。由于IO monad没有很好的类型来强制抽象,因此您需要手动确保副作用是不可观察的。

其他提示

如果您使用FFI导入该函数,只需删除 IO 从返回类型。否则,使用 unsafePerformIO :: IO a -> aSystem.IO.Unsafe.请注意,此功能是Haskell中最危险的功能之一。不要使用它,如果你不是真的shure关于后果。但为了你的目的,这似乎没问题。

是的,这将是unsaceperformio的合法使用。 但如果你真的确定没有明显的效果,那就是好的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top