什么 - >在F#中意味着什么?

时间:2008-09-19 19:07:50

标签: f# functional-programming

我一直试图进入和关闭F#一段时间,但我一直在推迟。为什么呢?

因为无论我采用哪种“初学者”资源,我都会看到非常简单的示例,它们开始使用运算符->

然而,我还没有找到任何地方,它提供了这个运算符意味着什么的清晰简单的解释。它似乎必须如此明显,即使完成新手也不需要解释。

因此,我必须非常密集,或者可能是将近三年的经历阻碍我。

有人可以请,解释一下或指向一个可以解释它的真正可访问的资源吗?

9 个答案:

答案 0 :(得分:47)

' - >'不是运营商。它出现在许多地方的F#语法中,其含义取决于它如何用作更大结构的一部分。

在某个类型中,' - >'描述了人们如上所述的功能类型。例如

let f : int -> int = ...

说'f'是一个接受int并返回int的函数。

在lambda内部(“以'fun'关键字开头的东西”),' - >'是将参数与正文分开的语法。例如

fun x y -> x + y + 1

是一个表达式,它定义了具有给定实现的两个参数函数。

在“匹配”构造中,' - >'是一种语法,它将模式与模式匹配时应运行的代码分开。例如,在

match someList with
| [] -> 0
| h::t -> 1

每个' - >'左边的东西是模式,如果左边的模式匹配,右边的东西就会发生。

理解上的困难可能源于错误的假设' - >'是一个具有单一含义的“运营商”。类比可能是“。”在C#中,如果您以前从未见过任何代码,并尝试分析“。”基于查看“obj.Method”和“3.14”以及“System.Collections”的运算符,您可能会非常困惑,因为符号在不同的上下文中具有不同的含义。然而,一旦你了解了足够的语言来识别这些背景,事情就会变得清晰。

答案 1 :(得分:12)

它基本上意味着“映射到”。以这种方式阅读或“变成”或类似的东西。

所以,从F# in 20 minutes教程,

> List.map (fun x -> x % 2 = 0) [1 .. 10];;
val it : bool list
= [false; true; false; true; false; true; false; true; false; true]
  

代码(fun i - > i%2 = 0)定义   一个匿名函数,称为lambda   表达式,有一个参数x和   该函数返回“x的结果”   %2 = 0“,这是否是x   甚至。

答案 2 :(得分:9)

第一个问题 - 你熟悉C#中的lambda表达式吗?如果是这样的话 - >在F#中与=>相同在C#中(我认为你读到了'去')。

- >运算符也可以在模式匹配的上下文中找到

match x with
| 1 -> dosomething
| _ -> dosomethingelse

我不确定这是否也是一个lambda表达式,或其他什么,但我猜'转到'仍然存在。

也许你真正指的是F#解析器的'神秘'回应:

> let add a b = a + b
val add: int -> int -> int

这意味着(正如大多数示例所解释的)add是一个'val',它接受两个int并返回一个int。对我来说,这开始时完全不透明。我的意思是,我怎么知道add不是一个带有一个int并返回两个int的val?

嗯,事情是,从某种意义上说,确实如此。如果我只添加一个int,我会得到一个(int - > int):

> let inc = add 1
val inc: int -> int

这个(currying)是使F#如此性感的事情之一。

有关F#的有用信息,我发现博客对任何官方“文档”都比FAR更有用:以下是一些要查看的名称

答案 3 :(得分:4)

(a - > b)表示“从a到b的功能”。在类型注释中,它表示函数类型。例如,f:(int - > String)表示f指的是一个取整数并返回一个字符串的函数。它也可以用作这些值的构造函数,如

val f : (int -> int) = fun n -> n * 2

创建一个值,该值是从某个数字n到相同数字乘以2的函数。

答案 4 :(得分:1)

来自Microsoft

  

函数类型是给定的类型   一流的功能值和   写入int - &gt; INT。它们很相似   到.NET委托类型,除了它们   没有给出名字。所有F#功能   标识符可以用作第一类   函数值和匿名   可以使用创建函数值   (有趣的...... - &gt; ...)表达形式。<​​/ p>

答案 5 :(得分:1)

这里有很多很棒的答案,我只是想以另一种思考方式添加对话。

' - &gt; '意味着功能。

'a - &gt; 'b是一个带'a并返回'b

的函数

('a *'b) - &gt; ('c *'d)是一个函数,它接受一个类型元组('a,'b)并返回一个元组('c,'d)。例如int / string返回float / char。

有趣的地方是'a - &gt;的级联情况'b - &gt; 'C。这是一个函数,它接受'a并返回一个函数('b - &gt;'c),或一个带'b - &gt;的函数。 “C

所以如果你写:  设f x y z =()

类型将是f:'a - &gt; 'b - &gt; 'c - &gt;单位,所以如果你只应用第一个参数,结果将是一个curried函数'b - &gt; 'c - &gt; '单元。

答案 6 :(得分:1)

在定义函数的上下文中,它类似于C#3.0中lambda表达式的=>

F#: let f = fun x -> x*x
C#: Func<int, int> f = x => x * x;

F#中的->也用于模式匹配,这意味着:如果表达式与|->之间的部分匹配,那么->之后会出现什么应该作为结果给予回复:

let isOne x = match x with
 | 1 -> true
 | _ -> false

答案 7 :(得分:1)

这个问题有很多很棒的答案,谢谢大家。我想在这里写一个可编辑的答案,将事情汇集在一起​​。

对于熟悉C#理解的人 - &gt;与=&gt;相同lamba表达是一个很好的第一步。这种用法是: -

fun x y -> x + y + 1

可以理解为相当于: -

(x, y) => x + y + 1;

但是很清楚 - &gt;有一个更加有趣的含义源于这样一个概念:一个带有上述两个参数的函数可以减少(是正确的术语吗?)到一系列只带一个参数的函数。

因此,当上述内容如下所述: -

Int -> Int -> Int

真的有助于了解 - &gt;是正确的关联因此可以考虑以上内容: -

Int -> (Int -> Int)

啊哈!我们有一个函数,它接受Int并返回(Int - &gt; Int)(一个curried函数?)。

解释 - &gt;也可以作为definiton类型的一部分出现也有帮助。 (Int - &gt; Int)是任何函数的类型,它接受Int并返回Int。

同样有用的是 - &gt;出现在其他语法中,如匹配,但它没有相同的含义?那是对的吗?我不确定是不是。我怀疑它有相同的含义,但我还没有词汇来表达它。

请注意,此答案的目的不是为了产生更多答案,而是由您的人员进行协作编辑,以创建更明确的答案。最好的是,除去所有不确定性和瑕疵(如本段)并添加更好的例子。让我们尽量保持这个答案尽可能无人问津。

答案 8 :(得分:0)

关于Haskell等语言的好处(它在F#中非常相似,但我不知道确切的语法 - 这应该有助于你理解 - >,但是)是你只能应用参数的一部分,创建 curried 函数:

adder n x y = n + x + y

换句话说:“给我三件事,我会把它们加在一起”。当你向它抛出数字时,编译器将推断出n x和y的类型。说你写

adder 1 2 3

1,2和3的类型是Int。因此:

adder :: Int -> Int -> Int -> Int

也就是说,给我三个整数,我将成为一个整数,最终,或者说是同样的事情:

five :: Int
five = 5

但是,这是很好的部分!试试这个:

add5 = adder 5

你还记得,adder接受一个int,一个int,一个int,然后给你一个int。然而,这不是全部真相,你很快就会看到。实际上,add5将具有以下类型:

add5 :: Int -> Int -> Int

就好像你已经“剥离”了整数(最左边),并将它直接粘贴到函数上。仔细观察功能签名,我们注意到 - &gt;是正确联想的,即:

addder :: Int -> (Int -> (Int -> Int))

这应该很清楚:当你给加法器第一个整数时,它会评估第一个箭头右边的任何一个,或者:

add5andtwomore :: Int -> (Int -> Int)
add5andtwomore = adder 5

现在你可以使用add5andtwomore而不是“adder 5”。这样,您可以应用另一个整数来获取(例如)“add5and7andonemore”:

add5and7andonemore :: Int -> Int
add5and7andonemore = adder 5 7

如你所见,add5and7andonemore想要另一个参数,当你给它一个时,它会突然变成一个整数!

  > add5and7andonemore 9
 => ((add5andtwomore) 7) 9
 => ((adder 5) 7) 9)
<=> adder 5 7 9

将参数替换为加法器(n x y)为(5 7 9),我们得到:

  > adder 5 7 9 = 5 + 7 + 9
 => 5 + 7 + 9
 => 21

实际上,plus也只是一个接受int并返回另一个int的函数,所以上面的内容更像是:

  > 5 + 7 + 9
 => (+ 5 (+ 7 9))
 => (+ 5 16)
 => 21

你去吧!