Functional programming sactionary.js中的数据建模挑战
我正在使用javascript中的函数编程构建一个基于域驱动设计的应用程序。我已经选择saccession.js生态系统作为我的工具,但我在建模类型方面面临一些挑战 为了将事情放在上下文中,让我们以下面的代码为例:Functional programming sactionary.js中的数据建模挑战,functional-programming,sanctuary,Functional Programming,Sanctuary,我正在使用javascript中的函数编程构建一个基于域驱动设计的应用程序。我已经选择saccession.js生态系统作为我的工具,但我在建模类型方面面临一些挑战 为了将事情放在上下文中,让我们以下面的代码为例: const{create}=require('sactionary')) const$=require('sactionary-def') const def=create({ checkTypes:process.env.NODE_env===='development', 环境:
const{create}=require('sactionary'))
const$=require('sactionary-def')
const def=create({
checkTypes:process.env.NODE_env===='development',
环境:$.env
})
常量货币=$.EnumType
(“货币”)
('http://example.com')
([‘美元’、‘欧元’))
const Payment=$.RecordType({
金额:$.Enumber,
货币:货币,,
方法:$.String
})
我的混淆点如下:
非常感谢我们考虑一下付款方式吧。为了保持示例的简单性,让我们假设付款方式是现金或带有相关卡号的信用卡/借记卡。在Haskell中,我们可以这样定义类型及其数据构造函数:
data PaymentMethod=现金|卡串
为了使用SANCATION def定义PaymentMethod
,我们需要知道现金
和卡
数据构造函数是如何实现的。您可以自由地手动定义或使用库,例如。让我们用手来写:
//现金::支付方式
常数现金={
“@@type”:“我的包/PaymentMethod”,
“标记名”:“现金”,
};
//卡片::字符串->付款方式
常数卡=编号=>({
“@@type”:“我的包/PaymentMethod”,
“标记名”:“卡片”,
“数字”:数字,
});
定义了数据构造函数之后,我们可以使用定义PaymentMethod
类型:
const$=require('sactionary-def');
const type=require(‘类型标识符’);
//PaymentMethod::Type
常量PaymentMethod=$.NullaryType
(“付款方式”)
('https://example.com/my-package#PaymentMethod')
([])
(x=>type(x)==“我的套餐/付款方式”);
请注意,由于每个PaymentMethod
值都将具有特殊的@@type
属性,因此我们可以使用来确定任意JavaScript值是否是PaymentMethod
类型的成员
我意识到,在JavaScript中接近Haskell的一行是相当复杂的。我希望这个例子展示了拼图的各个部分是如何组合在一起的
我们可能希望为
PaymentMethod
定义一个案例折叠函数,如下所示:
//foldPaymentMethod::a->(字符串->a)->PaymentMethod->a
const foldPaymentMethod=现金=>card=>paymentMethod=>{
开关(paymentMethod.tagName){
案例“现金”:返还现金;
案例“卡”:退货卡(paymentMethod.number);
}
};
定义了现金
、卡
和折叠式支付方法
之后,我们可以构建和解构支付方法
值,而无需担心实现细节。例如:
>foldPaymentMethod('Cash')(数字=>`Card(${S.show(数字)})`)(现金)
“现金”
>foldPaymentMethod('Cash')(数字=>`Card(${S.show(数字)})`)(Card('246810214161820'))
“卡(“246810214161820”)”
值得一提的是,PaymentMethod
不是枚举,因为Card
值构造函数需要一个参数。@davidchambers谢谢。你的回答肯定会让你更清楚地知道每件事是怎么回事。目前,我创建了一个简单的类型,比如Amount,方法是首先创建一个数据构造函数,然后创建一个相应的$.NullaryType类型,该类型工作时没有任何错误。这条路对吗?另外,在哪些情况下我需要$.UnaryType或$.BinaryType?@bob谢谢您的输入。注意。$.NullaryType
用于定义采用一个类型参数的类型构造函数,例如数组a
,可能是a
,以及树a
<代码>$。BinaryType用于定义二进制类型构造函数,例如a b
和对a b
。