fixIO做什么? [英] What does fixIO do?

查看:115
本文介绍了fixIO做什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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 之前利用懒惰来定义每个元素。



我们可以使用修复不必定义变量就可以做到这一点,为我们系结

 修正$ \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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆