F# 函数与方法

F# 函数与方法,f#,F#,我对F#很陌生。我首先注意到的是,集合操作被定义为函数而不是方法 作为一个实验,我在列表中定义了两个方法: type List<'a> with member this.map f = List.map f this member this.filter f = List.filter f this 以下是使用这些方法的示例: [1 .. 10].filter(isEven).map(square) 这是传统的方式: [1 .. 10] |> List.fi

我对F#很陌生。我首先注意到的是,集合操作被定义为函数而不是方法

作为一个实验,我在
列表中定义了两个方法:

type List<'a> with
    member this.map f = List.map f this
    member this.filter f = List.filter f this
以下是使用这些方法的示例:

[1 .. 10].filter(isEven).map(square)
这是传统的方式:

[1 .. 10] |> List.filter isEven |> List.map square
因此,简洁显然不是选择函数而不是方法的理由。:-)

从库设计的角度来看,为什么选择函数而不是方法

我的猜测是,这是因为你可以传递
List.filter
,但不能真正传递
filter
方法,除非它“绑定”到列表或包装在匿名函数中(即
(fun(ls:'a List)->ls.filter)
有效地将
filter
方法转换回
List
上的函数)

然而,即使出于这个原因,直接调用操作的最常见情况似乎也会有利于方法,因为它们更简洁。所以我想知道是否还有其他原因

编辑:


我的第二个猜测是函数专门化。也就是说,专门化
List.filter
(例如
让evens List.filter成为even
)很简单。定义一个
evens
方法似乎更为冗长。

函数比方法更重要的是函数专门化和它所能实现的简单分解

下面是涉及函数的示例表达式:

let square x = x * x

let isEven n = n % 2 = 0

[1 .. 10] |> List.filter isEven |> List.map square
让我们考虑一个名为
evens
的函数来过滤evens:

let evens = List.filter isEven
现在让我们算出一个函数,它将整数列表平方:

let squarify = List.map square
我们最初的表述是:

[1 .. 10] |> evens |> squarify
现在让我们回到原始的基于方法的表达式:

[1 .. 10].filter(isEven).map(square)

在这种情况下,在evens上分解过滤器并不是那么简单。

我认为你的猜测是正确的。简明扼要地说,能够将
列表.筛选
视为第一流的东西,可以传递(您的第一个猜测)和部分应用(您的第二个猜测),这是关键。这是一种以动词而不是名词为导向的看待世界的方式。我认为:)

可能重复的请注意,成员名称在
camelcasting
中,而不是
camelcasting
@RamonSnir它是
PascalCasing
:)@raroušPascal是物理学家的,Caml是程序员的:p
[1 .. 10].filter(isEven).map(square)