Code Monkey home page Code Monkey logo

Comments (1)

WanderHuang avatar WanderHuang commented on June 25, 2024

证明

现在,证明我们JavaScript定义的有效性。

首先,从现在开始,你要认为Just(x)是一种数据结构了,它代表着一类数据(一种范畴)。

我们先把id函数补充进去

// Just为我们的一个“函子”
function Just(value) {
    return {
        value, // 保存值
        // 值为基本数据,支持映射到范畴(Just)内其他元素
        // addOne = x => x + 1
        // 比如 Just(1).map(addOne)    -> Just(2)
        map: function map(fn) {
            return Just(fn(value))
        },
        // 值为基本数据,支持映射到自身范畴
        // 比如 Just(1).flatMap(addOne)    -> 2
        flatMap: function flatMap(fn) {
            return fn(value);  
        },
        // 值为函数(映射),支持映射到范畴(Just)内的其他元素
        // 比如Just((x) => x + 1).fmap(Just(2))     -> Just(3)
        fmap: function fmap(just) { // 函子 Just(compose(b, a)) = composeJust(Just(b), Just(a));
            return just.map(value);
        },
        id: function id(anything) {
            return Just(value);
        }
    }
}

然后我们看一下haskell的实现方式。

fmap id = id
fmap (f . g) = fmap f . fmap g

这是haskell常见的写法,递归定义。第一行表明使用fmap操作id函数,得到id函数自身。我们在JavaScript中实现id函数并证明Just满足自等定律。

var id = (x) => x;
// 在Number范畴中,id函数自等,即x = id(x)
var a = 1;
console.log(a === id(a)); // true

// 在Just范畴中
var ja = Just(1);
function eq(justa, justb) { // 实现一个Just范畴的判等函数
     return justa.flatMap(id) === justb.flatMap(id);
}

console.log(eq(ja, ja.id(ja))); // true 等于实现Just范畴中的 === 操作
Just(id).fmap(Just(999)); // Just(999)  等于实现Just范畴中的 fmap id = id

fmap已经实现了,我们再用lambda函数(箭头函数)来看一下具体区别。

// 需要实现操作: fmap (g . f) = (fmap g) . (fmap f)

var a = 3;
var square = x => x * x;
var addOne = x => x + 1;

// Number范畴中
var compose = (g, f) => x => g(f(x))
var compound = compose(square, addOne);
console.log(compound(a)); // (3 + 1) ^2 = 16

Just(compound)
    .fmap(Just(a)) // Just(16) 等于实现了 fmap compound =
Just(square)
    .fmap(
        Just(addOne).fmap(Just(a))
    ) // Just(16) 等于实现了= fmap f . fmap g

风格

现在,你必须接受Just就是一种通用类型了,就像你能接受Number类型、String类型一样。Just类型看起来有这些功能

  1. 保存你的原始值(程序保存value),把你从JavaScript原始值范畴映射到Just范畴
  2. 态射值(程序实现为映射函数map),允许你在Just范畴上把Just(X)值态射为另一个Just(Y)
  3. 态射函数(程序实现为映射函数fmap),允许你在Just范畴上把Just(f)函数作为Just范畴上的值Just(X)的态射函数,并映射Just(X)为Just(Y)
  4. 提取你的原始值(程序实现为flatMap),把你从Just范畴拉回到JavaScript原始值范畴

这种写法风格,等价为给数据值封装了一系列操作,以后你使用值和进行运算,都必须在Just上进行。这就是范畴论,一种研究数据「对象」和「态射」的方法。你可以理解类比为三角形有函数表示、几何表示、代数表示、复数表示等方式,范畴态射把同一个事物映射到不同的研究空间里面去,本质上,你还是在做类似的事情。

以上的几个方法只是monad世界的冰山一角,后面我们要理解为什么要做这种抽象,也会讲更多的操作,用以构建我们的程序世界。

compose函数的意义

组合函数令我们的程序,能够以更方便的方式进行组合,并且让我们的基础函数可以得到复用。比如加减乘除四个操作只需要对应四个函数,程序中没有必要创建这种函数

function addThree(a, b, c) {
    return a + b + c;
}

而可以通过组合的方式实现

var add = a => b => a + b;
var addThree = compose(add(c), add(b), add(a))(0)

数组中的Array.prototype.reduce方法就可以完成这件事,不过reduce也可以完成更多的事。

课后习题

  1. 实现compose(...args)对任意函数列表都执行
  2. 实现curry函数把一个函数fn的参数列表编程一元化的

from basic-programming-knowledge.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.