首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过在函数中包装参数来延迟计算?

通过在函数中包装参数来延迟计算?
EN

Stack Overflow用户
提问于 2019-12-31 08:51:26
回答 2查看 153关注 0票数 3

在“函数式编程第八章指南”中,它们定义了一个新的类IO,定义如下:

代码语言:javascript
复制
class 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()方法是如何延迟评估的。例如,从这一节的开头开始进行定义,

代码语言:javascript
复制
// getFromStorage :: String -> (_ -> String)
const getFromStorage = key => () => localStorage[key];

例如,如果我尝试创建一个像IO.of(localStorage[42])这样的新的IO.of(localStorage[42])对象,那么计算就不会延迟。localStorage[42]的值将立即计算(假设值为"foo"),然后使用{ $value: () => "foo" }创建新的IO对象。

我理解如何像调用延迟计算一样直接调用构造函数,但我不理解作者使用.of()方法意味着什么,以及如何“避免计算”。此外,作者没有在.of()的任何示例中使用IO,而是直接调用构造函数。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-12-31 09:17:28

为了使IO成为一元(根据那本书的monads概念),它需要一个.of方法,它可以将任意值封装在IO中。IO.of就是这么做的。由于本书实现IOs的本质是它们携带一个可以在稍后时间计算的函数,因此.of方法将传递的值封装在一个函数中。

IO.of(5)创建一个包装值5IO实例。这就是全部。实际上,.of没有任何延迟效果的地方。

关于你在评论中的问题:

那么作者所说的“这在of函数中很明显是什么意思:我们有一个IO( x),IO(() => x)只是为了避免计算而必需的。”

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

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

他的观点似乎是,从概念上讲,IO的“值”是包含的函数最终计算到的值,但是为了实现延迟的计算,它在内部存储一个未求值的函数,直到IO对一个值进行解析是必要的。

因此,您可以通过调用IO5值创建一个IO.of(5),但在内部,它包含一个计算为5的函数,以便以后可以将该函数求值为值。

如果您想要创建一个实际延迟计算的IO,请使用构造函数并传递一个函数。

票数 3
EN

Stack Overflow用户

发布于 2019-12-31 09:42:55

我喜欢把IO.of(x)看作是不洁行为的起点。

例如,您可能希望读取DOM元素的内容,x将是它的id:(在“伪代码”中)

代码语言:javascript
复制
const readInput = id =>
  IO
    .of(id)
    .map(id => document.getElementById(id))
    .map(el => el.textContent)

readInput('#login');
// combine with other monads for example
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59541760

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档