开发者社区> 问答> 正文

通过在函数中包装参数来延迟评估?

在《函数编程基本指南》中第八章,他们定义了一个新的类,IO,定义如下:

lass IO {
  static of(x) {
    return new IO(() => x);
  }

  constructor(fn) {
    this.$value = fn;
  }

  map(fn) {
    return new IO(compose(fn, this.$value));
  }

  inspect() {
    return `IO(${inspect(this.$value)})`;
  }
}

作者解释说:IO通过在函数包装器中捕获不纯的动作来延迟它。因此,我们认为IO包含包装动作的返回值,而不是包装本身。这在of函数中是显而易见的:我们有一个IO(x),IO(() => x)只是为了避免评估。 但是我很困惑.of()方法会延迟评估。例如,从该部分的开头偏离定义,

// getFromStorage :: String -> (_ -> String)
const getFromStorage = key => () => localStorage[key];

如果我尝试创造一个新的IO像IO.of(localStorage[42]),例如,这不会延迟评估的价值(localStorage[42]),会立即评估(假设评估结果为“foo”),然后是新的IO对象将使用{ $value: () => "foo" }

我理解如何调用构造函数立即喜欢新输入输出new IO(key => () => localStorage[key])延迟评估,但我不明白作者使用.of()方法以及如何“避免评估”。此外,作者不使.of()在的任何示例中IO,而是直接调用构造函数。

展开
收起
sossssss 2019-12-31 20:36:44 2536 0
1 条回答
写回答
取消 提交回答
  • 为了IO要成为单子(根据那本书对单子的概念),它需要一个.of方法,该方法可以将任意值包装在IO.的IO那样做。由于这本书的实施性质IO它们带有一个可以在以后某个时候评估的函数.of方法将传递的值包装在函数中。

    (5)的IO创建的实例信息作战包装这个值5.仅此而已。没有关于。关于这实际上延迟了效果。

    关于您在评论中的问题: 那么作者所说的“这在关于功能:我们有一个IO(x), IO(() => x)只是为了避免评估。"

    我认为理解这一评论所必需的信息是摆在它面前的:

    然而,我们并不认为它的价值是一个函数——这是一个实现细节,我们最好忽略它。...因此,我们认为IO包含包装动作的返回值,而不是包装本身。

    他的观点似乎是,从概念上来说IO's“value”是包含的函数最终评估的值,但是为了实现延迟评估,它在内部存储未评估的函数,直到信息作战解析为一个值。

    所以你可以创建一个信息作战为了价值5通过IO.of(5) ,但在内部,它包含一个计算结果为的函数5,以便在以后某个时候可以将该函数计算为一个值。

    如果您想创建一个IO这实际上延迟了一些不纯效果的评估,使用构造函数并传递给它一个函数。

    2019-12-31 20:41:15
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
用计算和数据去改变整个世界 立即下载
“静态调用链路发现”应用场景分析及实践探索 立即下载
fibjs 模块重构从回调到协程--陈垒 立即下载