• 维基F#译文: 值与函数(中)


    原文地址:http://en.wikibooks.org/wiki/F_Sharp_Programming

    2. 声明函数

    声明一个函数用的也是let,后面函数名和函数体,用空格间隔开来

    let add x y = x + y
    let z = add 5 10

    定义一个叫add的函数,接受两个参数,然后返回相加的结果。这里z就等于15了。

    那如果我这样调用呢?

    let z = add 5 10.2

    也许你会说z等于15.2吧,其实这里你会得到一个错误

    error FS0001: This expression was expected to have type
        int
    but here has type
        float

    这是应该F#是一种强类型的语言,也就是说你5是一个整型,但是10.2却是浮点型。两个类型不一样,所以不能相加。如果你原来是写PHP的,或是其它弱类型的语言(相对强类型而言)。那你一定会觉得这个特性很烦。但是这也是有好处,比如说代码运行速度更快。

    下面是一个稍微复杂的例子,注意最后一行的写法

    let add x y = x + y
     
    let sub x y = x - y
     
    let printThreeNumbers num1 num2 num3 =
        printfn "num1: %i" num1
        printfn "num2: %i" num2
        printfn "num3: %i" num3
     
    printThreeNumbers 5 (add 10 7) (sub 20 8)

    最后一行在其它的语言里,也许是像下面这样写的,个人觉得F#的写法更省事,对于我这种懒人来说是福音。

    printThreeNumbers( 5 , (add 10 7) , (sub 20 8) )

    如果你像下面这样写的话,F#就会认为你传了7个参数给 printThreeNumbers 这个函数

    printThreeNumbers 5 add 10 7 sub 20 8

    2.1 函数返回值

    不同于其它语言,在F#里你不用显示的调用return来返回值给调用者,简单的来说,函数里最后执行的语句所产生的值,就是这个函数的返回值。

    let sign num =
        if num > 0 then "positive"
        elif num < 0 then "negative"
        else "zero"

    上面所定义的函数sign,用来判断一个整数是正数还是负数,还是零。函数体内部没有显式的调用过return.但还是返回了值,也就是 positive negative zero这三个的其中一个,因为这个程序最后执行语句总是这三个分支中的其中一个。

    那如果我返回不再类型的值呢,比如下面这样,最后返回的不是字符串zero而是整型0.

    let sign num =
        if num > 0 then "positive"
        elif num < 0 then "negative"
        else 0

    前面说了F#是强类型语言,和C#一样。所以这里会报错,因为你在同一个函数里,有可能返回两种不同数据类型的值。

    最后要说的就是,如果一个函数没有返回值,那会怎么样,其实在F#中,如果一个函数没有返回值,它就会返回一种名为unit的类型的东西,其值为()。就是一对括号。那这个unit倒是什么,其实就相当于C语言中的void

    let helloWorld = printfn "hello world"

    比如上面这行代码,printfn的作用是向终端打印东西,在这里,printfn并没有返回值,所以helloWorld的值就是(),类型为unit

    2.2 怎样读懂箭头类型提示符(Arrow Notation)

    所有的函数和值在F#中都有数据类型,在函数式语言中,函数本身也可以作为值来传递。

    let addAndMakeString x y = (x + y).ToString();;
    val addAndMakeString : int -> int -> string

    第一行你定义一个函数,然后输入;; 回车之后,F#就开始解释你这个函数了,他知道了你这个函数接受了两个参数,最后返回了一个值。于是就有了第二行的内容了。

    按照箭头所指的方向,像流水一样,从左往右看。最右边的就是函数的返回值,剩下的就是函数所接受的参数。

    所以在这里int -> int -> string 就表明这个函数的返回值是string,接受的参数有两个,从左向右,第一个参数是int型,第二个也是int型。再来看几个:

    int -> string
    float -> float -> float
    int -> string -> float

    第一行: 接受一个整型作为参数,返回字符串型。

    第二行:接受一个浮点型作为第一个参数,再接受一个浮点型作为第二个参数,最后返回浮点型

    第三行:接受一个整型作为第一个参数,再接受一个字符型作为第二个参数,最后返回浮点型

    现在你也应该差不多理解这个东西了吧,你只要通过这个,不用看函数本身是怎么实现的,就能对这个函数明白个大概了。而F#又是怎么知道并且提示这个东西给你的呢,其实它是通过柯里化(Currying,这里取的是音译),或者叫部分求值来实现的,稍后会讲到这个。

  • 相关阅读:
    ACM spiral grid
    ACM 数独
    Codeforces Round #242 (Div. 2) A. Squats
    Codeforces Round #242 (Div. 2) B. Megacity
    Codeforces Round #242 (Div. 2) C. Magic Formulas
    Coder-Strike 2014
    Coder-Strike 2014
    Coder-Strike 2014
    ACM Same binary weight
    C puzzles详解【13-15题】
  • 原文地址:https://www.cnblogs.com/tuwenmin/p/2649503.html
Copyright © 2020-2023  润新知