【问题标题】:Difference between let, fun and function in F#F#中let、fun和function的区别
【发布时间】:2016-09-27 07:06:11
【问题描述】:

我正在学习 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 = 
...

到底有什么区别?

【问题讨论】:

  • 如果您还告诉我们VA 是什么,向您展示替代品会更容易一些。
  • “函数”是一种“匹配”,它在管道表达式中出现。例如x |> 功能 |案例1 -> ... | case2 -> ...这是一个不错的风格。

标签: function f# functional-programming


【解决方案1】:

这些东西是相互的捷径。

最基本的是let。这个关键字给东西命名:

let name = "stuff"

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

let identifier = "value"

在这之后,你可以在你的程序中使用nameidentifier这两个词,编译器就会知道它们的意思。如果没有let,就没有办法给东西命名,而且你必须始终将所有东西都写成内联,而不是通过名称来引用它。

现在,价值观有不同的风格。有字符串"some string",有整数42,有浮点数5.3,布尔值true,等等。一种特殊的值是function。函数也是值,在大多数方面类似于字符串和数字。但是你怎么写一个函数呢?写一个字符串,你用双引号,但是函数呢?

好吧,写一个函数,你使用特殊词fun

let squareFn = fun x -> x*x

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

这种语法在技术上是足够的,但并不总是方便编写。因此,为了使其更短,let 绑定对自身承担了额外的责任,并提供了一种更短的方式来编写上述内容:

let squareFn x = x*x

letfun 应该可以做到这一点。

现在,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"
 

【讨论】:

    【解决方案2】:

    我想你真的应该问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#,我会避开那个。它有其用途(主要用于为地图/过滤器等提供简洁的高阶函数),但会导致代码一目了然。

    【讨论】:

      猜你喜欢
      • 2014-09-07
      • 1970-01-01
      • 2018-07-02
      • 1970-01-01
      • 2015-10-18
      • 1970-01-01
      • 2020-06-23
      • 2013-09-22
      • 2013-10-04
      相关资源
      最近更新 更多