fuz*_*fuz 16 haskell global-variables purely-functional unsafe-perform-io
我经常在Haskell代码中找到这种模式:
options :: MVar OptionRecord
options = unsafePerformIO $ newEmptyMVar
...
doSomething :: Foo -> Bar
doSomething = unsafePerformIO $ do
opt <- readMVar options
doSomething' where ...
Run Code Online (Sandbox Code Playgroud)
基本上,一个人有一个选项或类似的记录,最初是在程序开始时设置的.由于程序员很懒惰,他不想options
在整个程序中携带记录.他定义了一个MVar
保持它 - 由丑陋的使用定义unsafePerformIO
.程序员确保状态只设置一次,并且在任何操作发生之前.现在程序的每个部分都必须unsafePerformIO
再次使用,只是为了提取选项.
在我看来,这样的变量被认为是实用的纯粹(不要打败我).是否有一个库抽象出这个概念,并确保变量只设置一次,即在初始化之前没有调用,并且不需要写unsafeFireZeMissilesAndMakeYourCodeUglyAnd
DisgustingBecauseOfThisLongFunctionName
scl*_*clv 20
为了一点暂时的便利而交易必要的参考透明度的人不应该既不纯洁也不方便.
这是一个坏主意.您找到的代码是错误的代码.*
没有办法安全地完全包裹这个模式,因为它不是一个安全的模式.不要在代码中执行此操作.不要寻找一种安全的方法来做到这一点.没有一种安全的方法可以做到这一点.把unsafePerformIO
地板上下来,慢慢地,并返回从控制台而去...
*人们确实使用顶级MV的合理原因,但这些原因与大多数情况下绑定到外部代码或其他一些非常混乱的东西有关.在这些情况下,据我所知,顶级MVar 不会从后面访问unsafePerformIO
.
如果您使用MVar进行设置或类似的设置,为什么不尝试阅读器monad?
foo :: ReaderT OptionRecord IO ()
foo = do
options <- ask
fireMissiles
main = runReaderT foo (OptionRecord "foo")
Run Code Online (Sandbox Code Playgroud)
(如果你不需要IO,请定期阅读:P)
使用隐式参数.它们的重量级略低于制作每种功能Reader
或ReaderT
类型的重量级.您必须更改函数的类型签名,但我认为这样的更改可以编写脚本.(将为Haskell IDE提供一个很好的功能.)
归档时间: |
|
查看次数: |
2375 次 |
最近记录: |