如何在 javascript 中使用函子

How to use functors in javascript

本文关键字:javascript      更新时间:2023-09-26

给定一个接受类型a的函数,我需要应用返回一个接受类型b的函数的函数z。基本上:

z -> f(a) -> f(b)

下面是一个更具体的例子。这是一个函数,它接受一个字符串并返回一组使用该字符串的方法:

# f(a)
_typeCheck = (str) ->
    isArray: -> str is TYPES.ARRAY

我想将这个函数转换为:

# f(b)
_typeCheck = ->
    isArray: (str) -> str is TYPES.ARRAY

执行此操作的功能z是什么?请帮忙。

注意

我在这里尝试使用函数式编程概念。Haskell有函子,可以修改类型构造函数以接受不同的类型。我相信类似的概念可以帮助我解决问题。在此处阅读更多内容

第一个问题是有一个采用"类型"的函数。JavaScript 是松散类型的,因此任何类型强制都需要来自您。

也就是说,您可以定义一个返回另一个函数的函数,如下所示:

function factory(a) {
    // check typeof a
    return function(b) {
        // do something with a
        // check typeof b
    };
}
// invoke
var myNewFunction = factory("a string");
myNewFunction("another string");

如果你正在寻找一个返回用于检查类型的函数映射的函数,也许你可以使用这样的模式:

function _typeCheck() {
    return {
        isArray: function(o) {
            return Array.isArray(o);
        },
        isString: function(o) {
            return typeof o === 'string';
        },
        ...etc
    };
}
console.log(_typeCheck().isArray(['one','two']));
console.log(_typeCheck().isString('foo'));

我不知道 Haskell,但在 JS 中你可以构造这样的东西:

// define some functors
list = xs => a2b => xs.map(a2b);
tree = t => a2b =>
    t ? {
        x: a2b(t.x),
        le: tree(t.le)(a2b),
        ri: tree(t.ri)(a2b)
    }
        : null;
maybe = x => a2b => x ? a2b(x) : x;
// add five to any functor
add5 = f => f(x => x + 5);
// let's test
myTree = {
    x: 1,
    le: {
        x: 2,
        le: {x: 3},
        ri: {x: 4}
    },
    ri: {x: 4}
};
myList = [10, 11, 12, 13];
log = x => document.write('<pre>' + JSON.stringify(x, 0, 3) + "</pre>");
log([
  add5(maybe(22)),
  add5(maybe(undefined)),
  add5(list(myList)),
  add5(tree(myTree))
]);