zoukankan      html  css  js  c++  java
  • F#函数值

    在大多数其它的编程语言里,函数和数据被当做是两个完全不同的概念。然而在函数式编程语言中,对待函数就像其它别的数据类型一样。例如,函数可以当做另一个函数的参数,除此之外,函数还可以创建并返回新的函数。
    这个特性可以使我们的代码更加抽象以及算法的重复使用。看下面的一个例子:
    下面的例子定义了一个negate函数,这个函数是个单一的int类型。当这个函数做为一个参数传递给List.map时,这个函数将应用于整个List,将对所有的List元素求反。

    1 >let negate x=-x;;
    2 val negate : int -> int //函数类型
    3
    4 >List.map negate [1 .. 10]
    5 val it : int list = [-1;−2; −3; −4; −5; −6; −7; −8; −9; −10]

      

    从上面我们也看到了,使用函数是非常方便的,但结果就是你得写很多简单的功能单一的函数,只单单利用自己并没有太多实用价值。例如我们上面例子,除了对一个数组求反恐怕其它的地方根本用不到。
    所以我们不用把所有当参数传递的小函数都进行命名,而是可以通用一个匿名函数(C#里面也有!),又叫做lambda表达式的玩意儿,来创建一个内联函数。
    要创建一个lambda表达式,很简单,使用"fun"关键字,紧接着是函数的参数和一个箭头"->"。
    下面的代码片段,创建了一个lambda表达式并传递一个值为5的参数。当函数执行后,参数x将增加3,结果为8:

    >(fun x -> x + 3) 5;;
    val it : int = 8

      

    现在我们用lambda表达式重写刚才的对数组取反的例子:

    1 >List.map (fun i -> -i)[1 .. 10];;
    2 val it : int list = [−1; −2; −3; −4; −5; −6; −7; −8; −9; −10]

      

    注意:要注意让lambdas表达式变得尽量简单,因为当他们变的复杂之后,将变的很难以调试。特别是我们在自己的代码里复制粘贴这些lambdas的时候。。


    局部函数的应用


    函数编程的另一方面是局部函数应用,也就是其它人经常说的“柯里化”,这里我们也可以叫他局部套用。让我们来看下面一个简单的例子,功能就是使用.net库来追加一个文本文件。

    View Code
     1 >open System.IO
    2 let appendFile (fileName : string) (text : string) =
    3 use file = new StreamWriter(fileName,true)
    4 file.WriteLine(text)
    5 file.Close();;
    6 //函数类型
    7 val appendFile : string -> string -> unit
    8
    9 >appendFile @"D:\test.txt" "测试字符串追加函数...";;//函数调用
    10 val it : unit = ()

      

    看到没?我们已经可以用F#来写文件了!就是这么简单。
    这个appendFile函数看上去非常简单,但是难道你想重新的写同一个文件?那么你就不得不总是保持文件路径做为第一个参数。这样子也许不错,但是我们可以创建一个新版本的appendFile函数,将第一个参数固定成@"D:\test.txt"。局部函数应用提供了指定函数的一些参数的功能,并且产生某个一些参数已经确定了的函数。我们可以重新设计一下appendFile的第一个参数,并产生一个只带一个参数的新函数:

    1 >let curriedAppendFile = appendFile @"D:\test.txt";;
    2 val curriedAppendFile : (string -> unit)
    3
    4 >//现在只需要传入文本
    5 curriedAppendFile "测试2";;
    6 val it : unit = ()

      

    没错,这就是传说中的柯里化。appendFile函数的类型是:string -> string -> unit
    所以当第一个参数传入后,结果将变为一个带着字符串的函数并且输出类型为unit,也就是string -> unit.
    柯里化可以使代码更简单,但也可以使代码变的难以debug.所以不要在程序里乱用以至于增加更多的复杂度,在需要的时候用即可。

    下一篇继续讨论柯里化。

  • 相关阅读:
    openssl生成CA和服务器SSL证书
    Windows编译安装openssl
    yasea浅析
    谈落后时的自卑感(三)
    更新Jekyll
    码云博客
    谈落后时的自卑感(二)
    谈落后时的自卑感(一)
    怎么才能更好的帮助企业进行数据挖掘
    云计算将来会面临什么样的安全威胁?
  • 原文地址:https://www.cnblogs.com/carsickcars/p/2168192.html
Copyright © 2011-2022 走看看