我一直试图进入和关闭F#一段时间,但我一直在推迟。为什么呢?
因为无论我采用哪种“初学者”资源,我都会看到非常简单的示例,它们开始使用运算符->
。
然而,我还没有找到任何地方,它提供了这个运算符意味着什么的清晰简单的解释。它似乎必须如此明显,即使完成新手也不需要解释。
因此,我必须非常密集,或者可能是将近三年的经历阻碍我。有人可以请,解释一下或指向一个可以解释它的真正可访问的资源吗?
答案 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
你去吧!