当前位置: 首页 > 知识库问答 >
问题:

如何正确使用点函子

贲功
2023-03-14

我试图熟悉JavaScript中的函数式编程。我刚读到指针函子是:

具有of函数的对象,可将任何单个值放入其中。

ES2015添加了一个rray.of使数组成为一个指向的仿函数。

我的问题是“单一价值”到底是什么意思?

我想做一个函数/容器(像https://drboolean.gitbooks.io/mostly-adequate-guide/content/ch8.html),它持有给定维度(宽度,高度)的网格作为一维数组,并允许我对其进行转换。作为一个普通对象,我将它存储为{宽度: 2,高度: 2,列表:[1,2,3,4]},但我想把它放在一个仿函数中,我不知道如何正确地做。

我知道这样使用点函子来存储单个值是非常好的:

Container.of(47)

但假设对象是“单一值”,使用对象作为值是否可以:

Grid.of({ width: 2, height: 2, list: [1, 2, 3, 4] })

或者甚至像这样:

Grid.of(2, 2, [1, 2, 3, 4])

共有2个答案

仲孙翔飞
2023-03-14
匿名用户

但假设对象是“单一值”,使用对象作为值是否可以:

是的。应该接受任何值并将其放入容器中。对象当然是这样一个单一的值。

Grid.of(2,2,[1,2,3,4])

编号。的应采用单个参数。如果要在一个函子中放入多个值,请先将它们放入另一个结构中,然后将该结构放入函子中,或者通过其点函数以外的其他函数(of)构造函子。

Grid.of({宽度:2,高度:2,列表:[1,2,3,4]})

不,如果您希望它返回输入,那么它将不起作用<的code>应按原样接收输入,并将结构包裹起来。在您的网格中,它肯定是这样的:

// Grid<A>
class Grid {
    // Int -> Int -> [A] -> Grid<A>
    constructor(w, h, vals) {
        assert(Number.isInteger(w) && Number.isInteger(h));
        this.width = w;
        this.height = h;
        const list = Array.from(vals);
        assert(list.length == w * h);
        this.list = list;
    }
    // Grid<A> -> (A -> B) -> Grid<B>
    map(f) {
        return new Grid(this.width, this.height, this.list.map(f));
    }
    // A -> Grid<A>
    static of(x) {
        return new Grid(1, 1, [x]);
    }
}

所以上面的调用将创建一个对象的网格,而不是一个由四个数字组成的网格。请注意,不是构造仿函数实例的唯一方法,它只是从单个元素构造实例的方法。

请注意,作为应用程序的一部分是最重要的,但对于普通的函子来说并不是那么有趣。顺便说一句,如果您对函数式编程概念感兴趣,您还应该能够将网格设置为幺半群、可遍历和单子-请参见https://github.com/fantasyland/fantasy-land.

梁晋鹏
2023-03-14

中的解释https://github.com/hemanth/functional-programming-jargon 不幸的是,这并不十分准确。

定点函子实际上是一个函子F,以及为每种A类型定义的of函数,并将A类型的x值发送到F A类型的值中。在欣德利·米尔纳签名中,它看起来像这样:

of :: a -> F a

例如,数组函子用of=x的=

此外,的函数(或者更准确地说,每个类型a都有一个的函数集合)必须是从身份函子到F的自然转换。这意味着应用于函数值的of等于应用于函数参数的of,然后映射到函数上:

of(f(x)) === of(x).map(f)

例如,在数组示例中,您有

[f(x)] === [x].map(f),

所以x=

但您也可以将重新定义为

of = x => [x, x]
[f(x), f(x)] === [x, x].map(f)

这使得Array成为另一个指向的仿函数,即使map方法保持不变。(请注意,在每种情况下,您只能获得非常特殊的数组,作为(x)值。)

但是,您不能将您的of定义为例如。

of = x => [x, 0]
[f(x), 0] !== [x, 0].map(f)

现在

var grid = Grid.of({ width: 2, height: 2, list: [1, 2, 3, 4] })

完全正常,并返回包装在网格中传递的对象。然后,您可以使用任何规则函数f网格从普通对象映射到普通对象,结果将与应用f并包装到网格相同,因为这是自然转换定律。注意,通过这种方式,您还可以使用任何其他值调用Grid.of,如Grid.of({width:2})of偶数Grid.of(2)。或者,您可以限制定义了Grid.of的类型,那么该值只能是您允许的类型。

这个有点棘手:

Grid.of(2, 2, [1, 2, 3, 4])

这将Grid.of应用于几个参数。由于Grid.of定义为只有一个参数的函数,结果将是Grid.of(2),这可能不是您想要的。如果你真的想满足所有的价值,你可能想写

Grid.of([2, 2, [1, 2, 3, 4]])

或者,您可以将Grid.of扩展到多个参数,方法是在内部将它们预先包装到一个数组中,然后应用Grid.of。这真的取决于你在追求什么。

有关实际使用示例,请参见此处的示例,其中“无聊”任务是通过普通值通过Task.of定义的。另一方面,这里有一个更有趣的任务,它包装了一个函数,这是使用Task.of无法获得的。但重要的是,这两个任务可以与两个示例中显示的相同统一接口一起使用。

还要注意,在这些例子中没有使用应用函子,所以仍然有没有应用的指向函子的使用。

补充。

另见https://github.com/MostlyAdequate/mostly-adequate-guide-it/blob/master/ch9.md#pointy-函子工厂的一个很好的介绍和现实世界中使用的定点函子。

 类似资料:
  • 是否可以正确地升级,而不是手动安装最新的稳定版本? 我已安装节点。js版本和,但现在我想将其更新为。我试图避免手动重新安装所有全局软件包(例如,通过运行grunt cli bower yoman angular generator blablablablablablablablablablabla)。

  • 2-我在FlatList中实现分页,所以当用户到达数据列表的末尾时,我调用一个函数来增加当前页,并根据当前页更新的情况,再次提取,因为我将to useEffect传递给依赖项数组 所以这里的问题是应该将以前的数据与新数据联系起来,所以我使用方法, 它工作得很好,但有时我收到一个警告,告诉我有一个重复的数据,当我使用扩展时不工作,我得到一个很大的错误,因为Flatlist keyExtractor问

  • 问题内容: 我只想检索UserAccount类中的某些列,所以我有以下代码: 我得到了空值作为回报。但是,如果我注释掉setProjections,我将获得具有所有属性的用户。在这种情况下,如何正确使用setProjection? 问题答案: 它返回一个Object数组,因此代码应为:

  • 问题内容: 我不知道我在哪里错了:/。当我运行这段代码时,我得到的只是一个空白元素。我似乎无法让insertRule方法执行任何操作(甚至不会产生错误)。我想念什么吗? 问题答案: 这有点令人困惑,但是您的代码确实可以工作,只是您看不到返回的XML树中插入的规则。 为了验证您的代码是否有效,您可以执行两个测试: 运行上面的代码片段,您可以看到CSS规则确实适用。并且属性也在控制台中更改。 当浏览器

  • 问题内容: 如何使用从类路径中查找递归资源? 例如 在“目录”中查找所有资源:想象一下 不幸的是,这只会检索到恰好该“目录”。 所有资源都已命名(递归) 但这返回一个空。 还有一个额外的问题:与有什么不同? 问题答案: 没有办法递归搜索类路径。您需要知道资源的完整路径名才能以这种方式检索它。该资源可能位于文件系统中的目录中,也可能位于jar文件中,因此它不像执行“类路径”的目录列表那样简单。您将需

  • 问题内容: 我最近开始使用ScriptManager。我有一个通过JavaScript填充的ASP.NET DropDownList控件。但是,我正在使用事件验证。因此,如果我不使用下拉菜单中的“ RegisterForEventValidation”调用,则会遇到以下错误。我怎么知道在第二个参数中设置什么值(我有“值”)?我正在通过JavaScript填充下拉列表,因此我不知道后面的代码中包含哪