我正在学习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 :(得分:15)
我猜你应该问MSDN,但简而言之:
let
使用符号绑定值。值可以是普通类型,如int
或string
,但它也可以是函数。在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#,我就会避开那个。它有其用途(主要用于为地图/滤镜等提供简洁的高阶函数),但导致代码的可读性一目了然。
答案 1 :(得分:9)
这些东西是彼此的捷径。
最根本的是let
。这个关键字为东西提供了名称:
let name = "stuff"
从技术角度讲,let
关键字定义了一个标识符并将其绑定到一个值:
let identifier = "value"
在此之后,您可以在程序中使用单词name
和identifier
,编译器将知道它们的含义。如果没有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
应该{{1}} vs let
。
现在,fun
关键字只是function
+ fun
的缩写形式。写match
等同于写function
,句号。
例如,以下三个定义是等效的:
fun x -> match x with