fixIO做什么? [英] What does fixIO do?
问题描述
System.IO文档包含一个神秘的,未公开的功能 fixIO
。 其来源只会增加神秘感:
fixIO ::(a - > IO a) - > IO a
fixIO k = do
m< - newEmptyMVar
ans< - unsafeInterleaveIO(takeMVar m)
result< -k ans
putMVar m result
返回结果
这看起来像是取消引用NULL的道德等价物(从空MVar读取) 。确实,试一试:
import System.IO
main = fixIO $ \x - > putStrLn x>>返回x
导致错误线程无限期地在MVar操作中被阻塞
除了 15岁信息
请澄清这一点?什么是fixIO,我应该在什么时候使用它?
fixIO
是 IO
等效于 fix
。
的fibonacci序列:
fibs = 1:1:zipWith(+)fibs(tail fibs)
code>
在 fibs
变量> fibs 来执行corecursion。它的工作原理是因为我们在需要使用
我们可以使用修复
不必定义变量就可以做到这一点,为我们系结:
修正$ \fibs - > 1:1:zipWith(+)fibs(tail fibs)
如果您不特别是需要保留整个斐波那契数列,你只是想知道它的第十个元素:
$ b $ pre $ $ $ $ $ $ $ > 1:1:zipWith(+)fibs(tail fibs))!! 9
55
fixIO
是类似,除了它可以让你在IO动作的输出上递归。这就是为什么你得到了你的线程阻塞错误 - 你使用的核心结果没有定义它。
λfmap )。 fixIO $ \fibs - > putStrLn计算fibs>>返回(1:1:zipWith(+)fibs(tail fibs))
计算fibs
[1,1,2,3,5,8,13,21,34,55]
The System.IO docs contains a mysterious, undocumented function fixIO
. Its source only adds to the mystery:
fixIO :: (a -> IO a) -> IO a
fixIO k = do
m <- newEmptyMVar
ans <- unsafeInterleaveIO (takeMVar m)
result <- k ans
putMVar m result
return result
This appears to do the moral equivalent of dereferencing NULL (reading from an empty MVar). Indeed, trying it:
import System.IO
main = fixIO $ \x -> putStrLn x >> return x
results in an error "thread blocked indefinitely in an MVar operation"
Searching turns up nothing save a 15 year old message from Simon Peyton-Jones himself, in which he provides the above source, and hopes that it would make the meaning clear (and yet here I am).
Can someone please shed some light on this? What does fixIO do and when should I use it?
fixIO
is the IO
equivalent of fix
.
You've probably seen this definition of the fibonacci sequence:
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
which reuses the fibs
variable within the definition of fibs
to do corecursion. It works because we exploit laziness to define each element of fibs
before it needs to be used.
We can use fix
to do the same without having to define a variable, tying the knot for us:
fix $ \fibs -> 1 : 1 : zipWith (+) fibs (tail fibs)
Which is handy if you don't especially need to keep the entire fibonacci sequence, you just want to know its tenth element:
λ (fix $ \fibs -> 1 : 1 : zipWith (+) fibs (tail fibs)) !! 9
55
fixIO
is similar, except it lets you recurse on the output of an IO action. That's why you got your "thread blocked" error - you were using the corecursive result without defining it.
λ fmap (take 10) . fixIO $ \fibs -> putStrLn "computing fibs" >> return (1 : 1 : zipWith (+) fibs (tail fibs))
computing fibs
[1,1,2,3,5,8,13,21,34,55]
这篇关于fixIO做什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!