F# 函数与方法
我对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
列表中定义了两个方法:
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)