如何在JavaScript中表示代数数据类型和模式匹配 [英] How to represent algebraic data types and pattern matching in JavaScript

查看:79
本文介绍了如何在JavaScript中表示代数数据类型和模式匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在像OCaml这样的功能语言中,我们有模式匹配.例如,我想在我的网站上记录用户的操作.一个动作可能是1)访问网页,2)删除项目,3)检查其他用户的个人资料等.在OCaml中,我们可以编写如下内容:

In functional language like OCaml, we have pattern matching. For example, I want to log users' actions on my website. An action could be 1) visiting a web page, 2) deleting an item, 3) checking the profile of another user, etc. In OCaml, we can write something as follows:

type Action = 
  | VisitPage of string (* www.myweb.com/help *)
  | DeletePost of int (* an integer post id *)
  | ViewUser of string (* a username *)

但是,我不确定如何在JavaScript中定义此Action.我可以想象的一种方式是

However, I am not sure how to define this Action in JavaScript. One way I could imagine is

var action_1 = { pageVisited: "www.myweb.com/help", postDeleted: null, userViewed: null }
var action_2 = { pageVisited: null, postDeleted: 12345, userViewed: null }
var action_3 = { pageVisited: null, postDeleted: null, userViewed: "SoftTimur" }

但是此结构并不表示pageVisitedpostDeleteduserViewed在它们之间是排他的.

But this structure does not express that pageVisited, postDeleted and userViewed are exclusive among them.

有人可以在JavaScript中提出这种类型的更好表示吗?

Could anyone propose a better representation of this type in JavaScript?

在JavaScript或TypeScript中是否有一种常见的方式来进行模式匹配?

Is there a common way to do pattern matching in JavaScript or TypeScript?

推荐答案

可以使用类来模仿函数式编程中的一种类型:

A type in functional programming can be mimicked with a class:

class Action {}
class VisitPage extends Action {
    constructor(pageUrl){
        super();
        this.pageUrl = pageUrl;
    }
}
class ViewUser extends Action {
    constructor(userName){
        super();
        this.userName = userName;
    }
}

var myAction = new VisitPage("http://www.google.com");
console.log(myAction instanceof Action);
console.log(myAction.pageUrl);

用于模式匹配:

class Action {}
class VisitPage extends Action {
    constructor(pageUrl){
        super();
        this.pageUrl = pageUrl;
    }
}
class ViewUser extends Action {
    constructor(userName){
        super();
        this.userName = userName;
    }
}

function computeStuff(action){
    switch(action.constructor){
        case VisitPage:
            console.log(action.pageUrl); break;
        case ViewUser:
            console.log(action.userName); break;
        default:
            throw new TypeError("Wrong type");
    }
}

var action = new ViewUser("user_name");
var result = computeStuff(action);

这篇关于如何在JavaScript中表示代数数据类型和模式匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆