F# F中的SKI组合微积分或星舰算子#

F# F中的SKI组合微积分或星舰算子#,f#,functional-programming,ml,calculus,F#,Functional Programming,Ml,Calculus,假设我们有两个功能: 一个具有单个参数的参数,如部分应用的加法: let plus1 = (+) 1 // the same as let plus1 x = 1 + x 另一个需要两个参数,如乘法: let mult = (*) 我们现在可以创建一个 let addOneAndMultiply x = mult x (plus1 x) fx(gx)通常被称为SKI组合微积分 在haskell中,类似的函数可以通过星舰操作符缩短: //haskell mult <*> pl

假设我们有两个功能:

一个具有单个参数的参数,如部分应用的加法:

let plus1 = (+) 1 
// the same as let plus1 x = 1 + x
另一个需要两个参数,如乘法:

let mult = (*) 
我们现在可以创建一个

let addOneAndMultiply x = mult x (plus1 x)
fx(gx)通常被称为SKI组合微积分

在haskell中,类似的函数可以通过星舰操作符缩短:

//haskell
mult <*> plus1
//haskell
多加1

有没有办法在F#做同样的滑雪动作?

在F#做这件事很简单:


在F#中执行此操作非常简单:


作为旁注,一些F#框架有一个名为
apply
的函数来实现这一点,并且可能定义也可能不定义
操作符。与Haskell不同,在F#中,您必须为每种类型的应用程序定义不同的函数/运算符。除非库提供了通用的
运算符,并且您不需要切换不同类型的定义。作为补充说明,一些F#框架有一个名为
apply
的函数来实现这一点,也可以定义或不定义
运算符。与Haskell不同的是,在F#中,您必须为每种类型的应用程序定义不同的函数/运算符。除非库提供了通用的
运算符,并且您不需要切换不同类型的定义。真正的问题:您觉得这样可以使代码更清晰和/或更可能正确吗?因为对我来说这很混乱,我可能会误用它。我喜欢惯用的F#没有像这样的组合词。@QuickBrownFox个人来说,我喜欢组合词并在F#中使用它们,但只在某些情况下使用。我可能不会将其用于具有简单扩展形式的内容,但用于类似错误处理的内容,即如果一切正常,则要应用
f
,但如果出现问题,则返回相应的
错误,我认为combinators比嵌套的pattern-matches更容易阅读和理解。@AaronM.Eshbach啊,我可以看到这样一种常见模式的有用性,其中类型差异也有助于确保正确使用。真正的问题:您觉得这样做可以使代码更清晰和/或更可能正确吗?因为对我来说这很混乱,我可能会误用它。我喜欢惯用的F#没有像这样的组合词。@QuickBrownFox个人来说,我喜欢组合词并在F#中使用它们,但只在某些情况下使用。我可能不会将其用于具有简单扩展形式的内容,但用于类似错误处理的内容,即如果一切正常,则要应用
f
,但如果出现问题,则返回相应的
错误,我认为combinators比嵌套的pattern-matches更容易阅读和理解。@AaronM.Eshbach啊,我可以看到这样一种常见模式的有用性,其中类型差异也有助于确保正确使用。
let (<*>) f g x = f x (g x)
let plus1 = (+) 1
let mult = (*)
let addOneAndMultiply = mult <*> plus1

addOneAndMultiply 2 // Result: 6
addOneAndMultiply 3 // Result: 12
addOneAndMultiply 4 // Result: 20
let starling f g x = f x (g x)