Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在JS中实现类似IO类型的MonadFix实例?_Javascript_Haskell_Monads_Monadfix - Fatal编程技术网

Javascript 如何在JS中实现类似IO类型的MonadFix实例?

Javascript 如何在JS中实现类似IO类型的MonadFix实例?,javascript,haskell,monads,monadfix,Javascript,Haskell,Monads,Monadfix,我完全无法将以下Haskell代码翻译成Javascript: instance MonadFix IO where mfix f = do var <- newEmptyMVar -- 1 ans <- unsafeInterleaveIO $ takeMVar var -- 2 result <- f ans -- 3 putMVar var

我完全无法将以下Haskell代码翻译成Javascript:

instance MonadFix IO where
  mfix f = do
    var <- newEmptyMVar                       -- 1
    ans <- unsafeInterleaveIO $ takeMVar var  -- 2
    result <- f ans                           -- 3
    putMVar var result                        -- 4
    return result                             -- 5

你的
Lazy
构造有一个thunks的表示,它恰好形成了一个monad(正如你所写的,monadic应用程序只是一个严格的函数应用程序),但是你没有
IO
的表示,所以你基本上只是到处使用
unsafePerformIO

在您的模型中,每个I/O操作只能执行一次,因此我希望这不会像您期望的那样工作,除非您添加一个单独的
IO
包装器,其中包含
runIO
函数(或属性,如果您愿意),该函数不会共享
Lazy
用记录的结果覆盖自身的行为,或者,如果您添加了某种方法来显式复制延迟操作。当然,
mfix f
只运行一次
f
的效果,也就是说,它是用于使用效果生成惰性/自引用数据结构的,因此这对于您的目的可能是好的

撇开这些警告不谈,完全可以为thunk结构表达类似于
MonadFix
实例的东西,但它只是
fix
的一个懒惰版本:

// cf. Haskell ‘fix f = let ans = f ans in ans’
function lazyFix(f) {
  var ans = Lazy(() => f(ans));
  return ans;
}
如果你有副作用交织在这些重击中,它们会在你强迫它们时发生

我认为原始Haskell代码中的
MVar
业务主要只是捕获无限循环子集的一种方便方式,它确保如果操作试图在写入值之前强制thunk,那么运行时将能够检测到线程“在
MVar
操作中被无限阻塞”并提出一个错误


另外,您应该能够将
lazyChain
定义简化为
fm(mx.lazy)
,因为
lazy(()=>fm(mx.lazy.lazy)
强制执行结果,然后立即再次将其打包,这既是额外的工作,也可能是对交错效果的过分渴望。您的版本实际上是在mx`seq`fx`seq`fx中使用
let fx=fm mx,可以将其简化(通过
a`seq`a
=
a
)为
mx`seq`fm mx
,然后相当于
fm$!mx,即严格的功能应用。

该代码中的
MVar
有点“皮带和吊带”。当前的实现使用
unsafedupableinterleavio
,并依赖
MVar
实现线程安全。。。实际上,我认为在编写时,
unsafeInterleaveIO
可能不是线程安全的?我不记得了。无论如何,现在一切都很合理……是的,每个
.lazy
查找都相当于
unsafePerformIO
。我仍然可以从
Lazy
中获益,因为它延迟了效果,使它们可组合,并且我只在应用程序的边缘运行它们。还有另一种类型
Defer
w/o共享。我了解到,当你使用不纯净的代码时,“积极的”共享是一个很好的特性,b/c它有助于非幂等效应。JS实际上不计算thunk literal
()=>fm(mx.lazy)。lazy
lazy(()=>fm(mx.lazy).lazy)
,但只有在
.lazy
上查找它时。如果我只有
fm(mx.lazy)
那就太急切了,因为
fm
会被立即调用,而不会产生
mx
的效果。