F中let、fun和function的区别#

F中let、fun和function的区别#,function,f#,functional-programming,Function,F#,Functional Programming,我正在学习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;; 如果没有函数关键字,我就不能写这个吗?或者我可以用fun而不是函数来编写它吗?当我看到你写的一些例子时,为什么我要写让 f

我正在学习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;;
如果没有
函数
关键字,我就不能写这个吗?或者我可以用
fun
而不是
函数来编写它吗?当我看到你写的一些例子时,为什么我要写

fun s x = 
...

真正的区别是什么?

我想你真的应该问,但简而言之:

用符号绑定一个值。该值可以是普通类型,如
int
string
,但也可以是函数。在FP中,函数是值,可以用与这些类型相同的方式处理

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

这是两个重要的用法,从这个意义上说,您所看到的所有其他用法都可以被认为是这两种用法的语法糖分。要定义函数,可以这样说:

 let myFunction = 
     fun firstArg secondArg ->
        someOperation firstArg secondArg
这是非常清楚的表达方式。您声明拥有一个函数,然后将其绑定到
myFunction
符号

但是,只需将匿名函数声明与
let
绑定到一个符号,就可以节省一些输入:

 let myFunction firstArg secondArg =
    someOperation firstArg secondArg  
函数
所做的有点棘手-通过在隐式参数上进行匹配,将匿名单参数函数声明与
匹配
表达式相结合。所以这两个是等价的:

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

let myFunction firstArg = function
    | "foo" -> firstArg
    | x -> x    
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"
 

如果你只是从F#开始,我会避开那个。它有它的用途(主要用于为映射/过滤器等提供简洁的高阶函数),但会导致代码的可读性降低。

这些东西是彼此之间的某种快捷方式

最基本的事情是让
。此关键字为内容命名:

let name = "stuff"
更严格地说,
let
关键字定义了一个标识符并将其绑定到一个值:

let identifier = "value"
在此之后,您可以在程序中使用单词
name
identifier
,编译器将知道它们的意思。没有
let
,就不会有命名的方法,而且你必须始终将所有内容内联编写,而不是按名称引用其中的部分

现在,价值观有不同的口味。有字符串
“一些字符串”
,有整数
42
,浮点数
5.3
,布尔值
true
,等等。函数是一种特殊的值。函数也是值,在大多数方面类似于字符串和数字。但是如何编写函数呢?要编写字符串,可以使用双引号,但函数呢

嗯,要编写函数,您需要使用特殊的单词
fun

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

这种语法在技术上是足够的,但并不总是便于编写。因此,为了缩短它的时间,
let
绑定本身承担了额外的责任,并提供了一种编写上述内容的较短方法:

let squareFn x = x*x
这应该对
let
vs
fun
起作用

现在,
函数
关键字只是
乐趣
+
匹配
的一个简短形式。编写
函数
相当于编写
fun x->match x with
,句号

例如,以下三个定义是等效的:

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

let myFunction firstArg = function
    | "foo" -> firstArg
    | x -> x    
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"
 

如果您还告诉我们
V
a
是什么,那么向您展示备选方案会更容易一些。“函数”是一种在管道表达式中出现的“匹配”。e、 g.x |>函数|案例1->…|案例2->。。。这是一种很好的风格。