2016-05-29 240 views
5

我正在学习F#,我无法弄清let,fun和function之间的区别是什么,而且我的教科书也没有真正解释。举个例子:F中的let,fun和function之间的区别#

let s sym = function 
| V x -> Map.containsKey x sym 
| A(f, es) -> Map.containsKey f sym && List.forall (s sym) es;; 

难道我没有写这个没有function关键字?或者我可以写与fun而不是function?为什么我必须写let时,我已经看到了一些例子,你写

fun s x = 
... 

有什么区别真的吗?

+0

它会更容易一点给你看的替代品,如果你还告诉我们什么'V'和'A'是。 –

+0

“函数”是一种在流水线表达式中自带的“匹配”。例如x |>函数| case1 - > ... | case2 - > ...这是一个很好的风格。 – sgtz

回答

12

我猜你应该问MSDN,但简而言之:

let结合具有符号价值。该值可以是简单类型,如intstring,但它也可以是一个函数。在FP函数中是值,可以用与这些类型相同的方式处理。

fun是一个关键字,它引入了一个匿名函数 - 如果您熟悉C#,请考虑使用lambda表达式。

这些是两个重要的,从你看到的所有其他用法可以被认为是这两个语法糖。所以要定义一个函数,你可以这样说:

let myFunction = 
    fun firstArg secondArg -> 
     someOperation firstArg secondArg 

而这是非常明确的说法。你声明你有一个函数,然后将它绑定到myFunction符号。

但你可以通过只混为一谈匿名函数声明并将其与let绑定到一个符号保存自己一些打字:

let myFunction firstArg secondArg = 
    someOperation firstArg secondArg 

什么function确实是有点麻烦 - 你把一个匿名单参数的函数声明用match表达式,通过匹配一个隐含的参数。所以这两个是等效的:

let myFunction firstArg secondArg = 
    match secondArg with 
    | "foo" -> firstArg 
    | x -> x 

let myFunction firstArg = function 
    | "foo" -> firstArg 
    | x -> x  

如果你刚开始使用F#,我会避开那一个。它有其用途(主要用于为地图/过滤器等提供简洁的高阶函数),但是导致代码一览无遗。

9

这些东西都是彼此的捷径。

最基本的是let。此关键字赋予名称的东西:

let name = "stuff" 

说到更技术上,let关键字定义一个标识符,并将其绑定到一个值:

let identifier = "value" 

在此之后,你可以用四个字nameidentifier在程序,编译器会知道它们的意思。如果没有let,就没有办法命名这些东西,并且您必须始终将所有内容写入内联,而不是通过名称来引用它的大块。

现在,值有不同的口味。有字符串"some string",有整数42,浮点数5.3,布尔值true等等。特殊类型的值是函数。函数也是值,在很多方面类似于字符串和数字。但是你怎么写一个函数呢?要写一个字符串,你使用双引号,但函数呢?

好了,写一个函数,可以使用特殊的字fun

let squareFn = fun x -> x*x 

在这里,我用了let关键字来定义一个标识符squareFn,并且该标识符绑定到函数类型的值。现在我可以在我的程序中使用squareFn这个词,编译器会知道每当我使用它时,我的意思是一个函数fun x -> x*x

这个语法在技术上是足够的,但并不总是方便写。所以为了让它短,let需要结合自身的额外的责任,并提供了一个较短的方式写上:

let squareFn x = x*x 

应该这样做了let VS fun

现在,关键字function只是fun + match的简写。写作function相当于写作fun x -> match x with,期间。

例如,下面的三个定义是等价的:

let f = fun x -> 
    match x with 
    | 0 -> "Zero" 
    | _ -> "Not zero" 

let f x = // Using the extra convenient form of "let", as discussed above 
    match x with 
    | 0 -> "Zero" 
    | _ -> "Not zero" 

let f = function // Using "function" instead of "fun" + "match" 
    | 0 -> "Zero" 
    | _ -> "Not zero"