Javascript Church编码的求和类型在非类型化语言中是合适的选择吗?

Javascript Church编码的求和类型在非类型化语言中是合适的选择吗?,javascript,functional-programming,higher-order-functions,discriminated-union,church-encoding,Javascript,Functional Programming,Higher Order Functions,Discriminated Union,Church Encoding,我已经为Javascript中的求和类型的想法奋斗了相当长的一段时间。该语言既不包括本机和类型,也不包括模式匹配。虽然您可以使用简单的旧Javascript对象和原型系统模拟求和类型,并引入一种原始的模式匹配形式(duck类型和通过开关进行分支),但这种方法非常繁琐,结果看起来一点也不地道——至少在我看来是这样 所以我想到了使用church编码来表示和类型的想法-但是,不是以严格的方式,即允许使用条件运算符等语言特性。我实现了选项类型作为练习: const some = a => _ =&

我已经为Javascript中的求和类型的想法奋斗了相当长的一段时间。该语言既不包括本机和类型,也不包括模式匹配。虽然您可以使用简单的旧Javascript
对象和原型系统模拟求和类型,并引入一种原始的模式匹配形式(duck类型和通过
开关进行分支),但这种方法非常繁琐,结果看起来一点也不地道——至少在我看来是这样

所以我想到了使用church编码来表示和类型的想法-但是,不是以严格的方式,即允许使用条件运算符等语言特性。我实现了选项类型作为练习:

const some = a => _ => f => f(a);
const none =      x => _ => x

const head = xs => 0 in xs ? some(xs[0]) : none;

head(["foo"]) ("") (x => x.toUpperCase()); // "FOO"
head([]) ("") (x => x.toUpperCase()); // ""
首先,我不确定这是否是一个正确的实现。除此之外,还有两件事困扰着我:

  • 我不确定所有可能的场景是否都有合适的默认值
    String
    s的中性元素-但是对于任何类型,是否存在类似中性或零这样的元素
  • 由于
    head
    现在返回一个二进制函数,因此它不再是可组合的
除此之外,我发现这种方法非常有前途,因为它完全依赖于高阶函数,并且不会引入新奇的类型,而这些类型对语言来说有些陌生

Chruch编码只是一个很好的智力挑战,还是该技术能够解决实际问题


很抱歉,如果这个问题太宽泛或太混乱,或者两者兼而有之,但我觉得我好像走到了死胡同。

首先,在Smalltalk中,以其“真的一切都是对象”的方式,不是语言结构,而是由教堂的布尔人代表的(尽管我认为没有人这样称呼他们)。Smalltalk布尔值是一个对象,它接受两条消息(也称为“有两种方法”)
ifTrue:
ifFalse:
,然后根据对象实际为
true
false
中的哪一条进行处理


此外,还有一个名为tagged sums的JS库,它在内部使用类似Church编码的东西:它将sum类型编码为它调用的东西,这实际上只是选择正确标记的函数,尽管还有更多关于JS规范的内容。

我看不出您需要什么“适当的默认值”对于您可以在您的表示上实现每个
选项
操作符(例如
maybe=id
isJust=m=>m(false)(=>true)
fmap=g=>m=>(x=>f=>m(x)(a=>f(g(a))
)是什么使高阶函数不可操作
head
仍然是一个接受一个列表参数并返回一个选项值的函数。@Bergi我明白了。该组合共享的主要参数也是一个函数,其类型为
r->(a->r)->r
。当函数被用作数据时,我仍然感到困惑。我终于应该习惯了。@Bergi啊,我当然可以定义
map
/
ap
/
chain
,因此不需要“取消装箱”值。我应该三思而后行再问@Bergi为什么还要将
x
f
传递给
fmap
?当您打开
选项时,只需要
x
。您也不需要
f
,因为
fmap
是特定于
选项的。我们能否将代码简化为
fmap=g=>m=>m(无)(x=>Some(g(x))
。类型仍然是
(a->b)->(r->(a->r))->(r->(b->r))->r
。或者我不被允许在Church中使用
Some
/
None
,而这实际上是Scott?我明白了,
cata
是他们自动创建
bool
可能
等的方式。顺便说一句,daggy是个有趣的名字。有趣的是,
可能
的类型是
b->(a->b)->可能是a->b
,这与我的示例中的一些非常接近:
a->r->(a->r)->r
。谢谢你的例子。