f#_c#f - CSDN
精华内容
参与话题
  • F#语言快速教程

    千次阅读 2019-09-04 11:04:41
    F#是微软开发的基于.NET平台的一种函数式语言,而且支持面向对象。

    F#是微软开发的基于.NET平台的一种函数式语言,而且支持面向对象。
    其安装过程非常简单,只需要下载最新版的VisualStudio,在安装的过程中选择F#即可。
    创建项目也很简单,只要在VS中新建一个F#项目即可。快捷键F5启动程序,可以在命令行中查看输出。

    基础

    绑定变量

    在F#中,通过let关键字来定义变量、函数以及类等。
    如果希望建立一个代码块,可以使用关键字module,从而避免创建全局变量

    module keyLet=
        let i = 1           //F#中可以用可用//进行注释;let绑定变量时,会自动推断变量的数据类型
        let testValue = 
            3*4+5*6         //let绑定变量时可以换行,但需要进行缩进
        let x,y,z = (1,2,3) //可同时绑定多个变量,其中(1,2,3)为元组
        let result=         //body-expression
            let i,j,k = (1,2,3)
            i + 2*j + 3*k
        let function1 a=
            a+1             //let绑定函数
    

    运算符

    运算符 类型 说明
    && || not 布尔 与、或、非
    &&&,|||, ^^^,~~~ 位运算 按位与、或、异或、取反
    <<<、>>> 位运算 按位左移、右移
    +、-、*、/、%、** 算术 加、减、乘、除、余、幂
    =、<>、>=、<=、>、< 比较 等于、不等于、大于等于、小于等于、大于、小于

    在F#中,运算符可以当作函数使用,而且在类中可以被重载,也可以定义一个全局的运算符。

    module opTest=
        let a = (+) 1 2     //即a=1+2
        let op1 = (*) 3     //op1是一个函数,即op1(x) = 3*x
        let b = 4 |> op1 |> op1 //  b = 3*3*4
        //通过let新建运算符
        let (++) (x: int) (y: int) = x + 2*y
        printf "%d" (10 ++ 1)
    
    

    数据类型

    基本类型

    编程语言中的基本数据类型往往大同小异,F#中的基本数据类型基于.NET基元类型,更是如此。其中unit是独有的一种类型,表示空值,其只有一个取值()

    类型 取值 类型 取值 类型 取值
    bool True/False byte 0-255 sbyte -128~127
    int16 16位有符号整型 uint16 16位无符号整型
    int 32位有符号整型 uint32 32位无符号整型
    int64 64位有符号整型 uint64 64位无符号整型
    nativeint 有符号整型指针 unativeint 无符号整型指针
    char Unicode字符 string 字符串
    uint () void 无类型或无值
    decimal 浮点 float32/single 32位浮点 float/double 64位浮点

    tuple

    元组是一种常见的数据类型,在F#中,元组内部的元素可以是不同的数据类型甚至表达式。

    module tupleTest=
        let tuple1 = (1,'a',2.5)        //元组中的元素可以是不同的数据类型
        let a,_,_ = tuple1              //元组索引时,可以通过'_'来避免创建新的不需要的变量
    
        let third (_,_,c) = c           //定义一个函数,返回三元元组中的第三个值
        let tuple2 = (tuple1,'a',third) //元组中的元素可以是元组和函数
        let d = third tuple2 tuple1     
        printfn "%f" d                  //输出为2.5
    
    

    list

    在列表中,元素必须是相同类型的,且值不可更改。F#中封装了List模块,提供了许多便利的函数。

    module listTest =
        let list1 = [1;2;3]             //list用[]创建,内部元素用;隔开
        let list2 = []                  //list可以为空
        let list3 = [                   //list还可以通过换行的方式创建
            1                           //此时可省略;
            2
            3]
        let list4 = [ 1 .. 5 ]          //创建从1到5的数列其值为
        printfn "%A" list4              //输出为[1;2;3;4;5]
        let list5 = 0::list4            //用::来连接元素与列表,得到[0;1;2;3;4;5]
        let list6 = list5@list4         //用@来连接列表
        let list7 = [for i in 1..5 -> i*i]  //序列表达式,得到[1;4;9;16;25]
        let list8 = 
            [ for i in 0 .. 7 do
                  for j in 0 .. 7 do 
                      if (i+j) % 2 = 1 then 
                          yield (i, j) ]
        printfn "%A" list8
        (*输出为:
        [(0, 1); (0, 3); (0, 5); (0, 7); (1, 0); (1, 2); (1, 4); (1, 6); (2, 1); (2, 3);
        (2, 5); (2, 7); (3, 0); (3, 2); (3, 4); (3, 6); (4, 1); (4, 3); (4, 5); (4, 7);
        (5, 0); (5, 2); (5, 4); (5, 6); (6, 1); (6, 3); (6, 5); (6, 7); (7, 0); (7, 2);
        (7, 4); (7, 6)]*)
            ///常用的List函数
        let sum1 = List.sum list1   //List.sum 表示对列表求和
        let ave1 = List.averageBy (fun elem -> float elem) list1
        (*List.average只能作用于浮点型的列表,
        所以List.average list1会报错
        List.averageBy可以以一个函数表达式作为输入
        其后面的fun表达式表示将元素转为浮点型*)
        let unzip8  = List.unzip list8      //List.unzip可将元组列表拆分
        printfn "%A" unzip8
        (*s输出为:
        ([0; 0; 0; 0; 1; 1; 1; 1; 2; 2; 2; 2; 3; 3; 3; 3; 
          4; 4;4; 4; 5; 5; 5; 5; 6; 6;6; 6; 7; 7; 7; 7],
         [1; 3; 5; 7; 0; 2; 4; 6; 1; 3; 5; 7; 0; 2; 4; 6; 
          1; 3; 5; 7; 0; 2; 4; 6; 1; 3;5; 7; 0; 2; 4; 6])*)
    

    array

    和列表相比,数组内部的值是可变的。

    module arrayTest =
        let arr1 = [|1;2;3;4;5|]                //数组通过[| |]进行定义,元素通过";"间隔,且可以为空
        let arr2 = [| "hello"; "world"; "and"; "hello"; "world"; "again" |]
        let arr3 = [| for i in 1..5 -> i*i |]   //支持序列表达式
        let arr4 = Array.create 3 5             //Array.create可创建数组,其值为[|5;5;5|] 
        arr4.[1] = 1                            //通过.[]进行索引,索引从0开始,arr4变为[|5;1;5|]
        arr4.[2] <- 2                           //通过<-进行赋值
        let arr5 = Array.append arr1 arr3      //用Array.append合并两个数组,List也支持append
    

    seq

    序列主要用于索引,相当于python中的Range,但是其内部的数据类型可以为非整型。

    module seqTest = 
        let seq1 = Seq.empty                        //空序列
        let seq2 = seq { yield "hello"; yield "world"; yield "and"; yield "hello"; yield "world"; yield "again" }
        let seq3 = seq { 1 ..2 .. 10 }              //从1到10,间隔为2的序列[1;3;5;7;9]
        //seq选出seq2中包含'l'字母的单词
        let seq4 = 
            seq { for word in seq2 do               //for..in..do表示遍历seq2中的元素
                      if word.Contains("l") then    
                          yield word }          //关键字yield可以将值插入到序列中
    

    map

    映射(字典)是一种由键值对组成的索引类型,与数组等相比,其键值可以为非整型

    module mapTest=
        let map1 = Map.empty                    //通过Map.empty创建空的字典       
        let map2 = map1.Add("a",1).Add("b",2)   //.Add添加键值对
        printfn "%d" map2.["a"]                 //通过.[]索引键得到值,输出为1
        //通过Map.ofList可创建字典,list的元素为元组
        let map3 = Map.ofList ["a",1; "b",2; "c",3]
        let seq4 = seq{for key in 1..5 do yield key,key.ToString()}
        let map4 = Map.ofSeq seq4               //通过Map.ofSeq创建字典
    

    set

    相对于序列来说,集合中没有重复元素。

    module setTest=
        let set1 = Set.empty                    //通过Set.empty创建空的字典       
        let set2 = set1.Add("a").Add("b")       //.Add添加键值对
        let set3 = set2.Add("c").Add("b")   
        printfn "%A" set3                       //输出为["a";"b";"c"]
        let set4 = Set.ofList [1;2;3;4;1;3;5;2] //值为[1;2;3;4;5]
    

    record

    record在表现形式上与字典类似,但与此前提到的数据类型不同,record需要首先通过关键字type进行预定义实际的类型,然后再通过实际类型的名称进行实例化,有点类或者结构的感觉。

    module recordTest=
        type fullName = {First:string; Last:string;}    //在实例化记录之前需要进行声明,分号可用换行代替
        let a = { First = "Wang";Last = "Xing"}        //定义值的时候不要显式声明
    
        type petName = {First:string; Last:string;}
        let b:petName = { First = "Wang";Last = "Xing"}//字段重复,可以通过":"来明确类型
        
        //"copy and update":c = { First = "Wang";Last = "Xing"}
        let c = {b with Last = "Xingxing"}
    
        let printName (name:petName)=
            "its name is"+c.First+c.Last                //记录通过.字段进行索引
        printfn "%s" (printName c)
    
        //记录中可以封装函数
        type autoFullName = 
            {First: string;
             Last: string;}
            member this.printFirst=
                "its first name is "+this.First
        
        let d:autoFullName = { First = "Wang";Last = "Xing"}
        printfn "%s" d.printFirst
    

    DU

    即discriminated union,与record相似,DU也需要首先通过关键字type对具体的数据类型进行定义。其内部存储的是一组不相同的字段,在建立一个DU实例的时候,只能选取其中的一个字段,类似于枚举类型。

    module duTest=
        //联合的各个分量通过"|"来区分,字段首字母需要大写
        type person = | Man |  Woman 
        let p1 = Man
        type personAge =        //联合也可以换行输入
            | Man of int            //通过of来规范字段的数据类型
            | Woman of int
        let p2 = Man(15)            //一个15岁的男人
    

    option

    option类型提供了一种自检机制,即可以自行判断数据中是否存在符合我们需求的值。其内部有三个字段,Value为访问基础类型值;isSome判断取值是否为基础类型值;isNone判断取值是否为None,即如果不确定某值是否有效,可先行通过isNone进行判断。

    module optionTest=
        let mutable x = Some(50)    //可选类型通过Some定义
        x <- Some(40)
    

    函数

    所有编程语言都有函数,F#比较特殊的地方是递归函数需要用关键字rec声名。
    在F#中,判断语句为if...then..elif...then...else,循环结构包括for...[to|downto] ...do ,for...in...do,while...do三种形式。其中,

    • for i = a to b语句类似于其他语言中常见的for(i=a;i<=b;i++)写法;downto则相当于i--
    • for i in b do即用i来遍历序列、列表或者数组b,相当于python中的for i in b:
    • while...do则是常见的表达形式.
      此外,F#还提供了类似于switch...case语句的match表达式,其表达式为match ...with...|...|...,其中|相当于case

    作为函数式语言,F#理所当然地支持lambda表达式,其关键字为fun

    module functionTest=
        let func1 x = x+1.0
        let func2 (a,b) = a+b
        let func3 (a,b) = (b,a)
        let func4 (a:int) = a+1     //限定函数的输入数据类型
        printfn "%d" (func4 1)
    
        let rec fac n =             //关键字rec定义递归函数
            if n=0 then 1           //F#中无"=="号,"="只用于比较,赋值用"<-"
            else fac n*fac(n-1)     //本函数实现阶乘
        
        let rec fib n =             //臭名昭著的斐波那契数列递归写法
            if n<=2 then 1
            else fib (n-1)+fib(n-2)
    
        let rec printList listx =
            match listx with
            //如果可以拆分成一个值和一个list的和,则打印这个值并递归剩下的list
            | head :: tail -> printf "%d " head; printList tail
            //如果list为空,则打印""
            | [] -> printfn ""
    
        //lambda表达式,fun关键字
        let func5 list = List.map(fun i-> i+1)list
        printfn "%A" (func5([1;2;3;4;5]))
    

    函数复合

    在F#中,函数可以通过运算符>>进行组合,表达式f1>>f2>>f3类似于f3(f2(f1(input)));也可以通过运算符|>进行管道处理,表达式x |> f1 |> f2 |> f3类似于f3(f2(f1(x)))

    module pipeComTest =
    
        let square x = x * x
        let addOne x = x + 1
        let isOdd x = x % 2 <> 0
        let numbers = [ 1; 2; 3; 4; 5 ]
    
        let composition1 values = 
            let odds = List.filter isOdd values         //List.filter 选出isOdd values为True时的元素
            let squares = List.map square odds          //List.map 对odds中的元素根据square进行映射
            let result = List.map addOne squares
            result
        
        //composition2的输出也为函数
        let composition2 values = 
            List.map addOne (List.map square (List.filter isOdd values))
    	
    	//通过|>运算符将函数进行组合
        let pipe1 values =
            values
            |> List.filter isOdd
            |> List.map square
            |> List.map addOne
    
        //pipe
        let pipe2 values =
            values
            |> List.filter isOdd
            |> List.map(fun x -> x |> square |> addOne)	//通过lanmbda表达式和|>将square和addOne组合
    
        let composition3 =
            List.filter isOdd >> List.map (square >> addOne)
    

    面向对象

    所谓对象(object)就是封装了数据和算法的一个抽象模块,从这个意义上来说,此前提到的record也可以作为一种对象。面向对象在处理状态变化的事务时具有无可比拟的优势,所以就开发的角度来说,函数式有其在数据处理上的优势,但在某些情况下,面向对象还是不可或缺的。

    class

    在F#中,通过关键字type来定义类,其成员可以写在class...end的代码块中,当然这是可以省略的。
    继承的关键字为inherit,多态虚拟成员abstract和重载overide实现。泛型类通过标识符<'A>来实现。需要注意的是,在F#中,类只能继承一个父类,但是可以继承多个接口。

    module classTest = 
        //F#会默认创建隐式字段dx和dy
        type Vector2D(dx : double, dy : double) =
            let length = sqrt (dx*dx + dy*dy)
            member this.DX = dx                     //this非关键字,可以换成任意相同的名称
            member this.DY = dy
            member this.Length = length
            member this.Scale(k) = Vector2D(k * this.DX, k * this.DY)   //方法,返回一个缩放后的向量
        
        let vector1 = Vector2D(3.0, 4.0)        //实例化
        let vector2 = vector1.Scale(10.0)       //调用scale方法
        printfn "Length of vector1: %f\nLength of vector2: %f" vector1.Length vector2.Length
    
        type xAxis(x) = 
            inherit Vector2D(x,0.0)                 //通过关键字inherit表示继承
            member this.Scale(k) = xAxis(k*x)       //覆盖类成员  
    
        type extVector(dx:double,dy:double) = 
            let length = sqrt(dx*dx+dy*dy)
            abstract member PrintInfo: unit->unit   //这是个虚拟成员
            default this.PrintInfo() = printfn "common vector"//虚拟成员初始化
    
        type axisX(dx) = 
            inherit extVector(dx,0.0)
            override this.PrintInfo() = printfn "x axis"     //虚拟函数的重载
    
        type axisY(dy) = 
            inherit extVector(0.0,dy)
            override this.PrintInfo() = printfn "y axis"     //虚拟函数的重载
    
        type StateList<'T>(init: 'T) = 
            let mutable states = [ init ]
            member this.insert newState = 
                states <- newState :: states    // 合并newState和tstates并赋值给states
            member this.History = states        // Get the entire list of historical states
            
        let tracker = StateList 10                  //int型的状态跟踪器
        tracker.insert 17                           // 添加状态
        let strTracker = StateList<string> "First"  //可以通关过<T>的形式进行实例化
    

    抽象类和接口

    在上例中,对于extVector这个类而言,如果虚拟函数PrintInfo后面没有定义默认方法是会报错的。
    如果虚拟函数后面没有默认的实现代码,那么就会变成抽象函数,而包含了抽象函数的类则也就变成了抽象类。抽象类的定义前必须加上标记[AbstractClass]
    如果一个类中,只有抽象成员,那么这个类又会摇身一变,而成为接口(Interface)。和类一样,接口也通过type来进行声明,并且写在interface...end代码块中。当然,又和类一样,interface,end也可以省略,编译器如果发现类中全都是抽象成员,那么会自动判定其为接口。
    无论是抽象类还是接口,都不能创建实例,而只能被其他类所继承。

    module interfaceTest=
    
        type Speed = 
            abstract Run: dis : float -> float  //只包含虚拟函数且没有初始化,自动判定为接口
    
        type Vehicle(speed:float)=              //通过接口实现了一个类
            interface Speed with
                member this.Run x = x/speed     //接口成员需要缩进
            abstract member PrintInfo : unit -> unit
            default this.PrintInfo() = printfn "speed:%f" speed
    
        let v1 = new Vehicle(15.0)
        let mutable ir1 = v1 :> Speed            //接口的子类可以向上转换为接口类型的对象
        printfn "跑10公里用时%.1f" (ir1.Run(10.0))
    

    交互操作

    fsi

    在Visual Studio的安装目录中提供了一个交互式操作工具fsi.exe,其路径为
    ..\2019\Common7\IDE\CommonExtensions\Microsoft\FSharp\fsi.exe
    这样我们就可以像使用python一样使用F#,可以非常方便地进行函数的调试。其界面如下:
    在这里插入图片描述

    需要注意的一点是,在fsi中输入命令,如以双分号;;结尾,则可直接输出结果,有点像matlab不加分号的样子。

    > let a = 1;;			//绑定a值为1
    val a : int = 1
    
    > let addOne x = x+1	//没有;;则不输出
    - let addThree x = x|> addOne |> addOne |> addOne;;//管道操作
    val addOne : x:int -> int
    val addThree : x:int -> int
    
    > printfn "%d" (addOne a);;
    2
    val it : unit = ()
    
    > printfn "%d" (addThree a)
    > ;;
    4
    val it : unit = ()
    

    使用CLI

    所谓CLI即command-line interface,也就是命令行的意思。.net在命令行上提供了dotnet工具,用以开发 .NET 应用程序。
    只要安装.NET Core SDK即可启动dotnet工具了。而且对于F#,微软提供了一个简短的教程:使用F#命令行

    dotnet new sln -o test							//使用new命令新建一个项目
    dotnet new classlib -lang F# -o src\Library		//创建一个由F#语言编写的classlib
    dotnet sln test add src\Library\Library.fsproj	//将Library添加到test中的sln中
    

    此时的目录结构为

    E:\Documents\00工作文档\0713>tree /a /f
    卷 工作 的文件夹 PATH 列表
    卷序列号为 3895-5CDD
    E:.
    +---src
    |   \---Library
    |       |   Library.fs
    |       |   Library.fsproj
    \---test
            test.sln
    

    其中,Library.fs为F#程序的源代码,打开之后发现默认定义了一个打招呼的函数:

    namespace Library
    module Say =
        let hello name =
            printfn "Hello %s" name
    

    我们先build然后新建一个程序调用这个Library中的Say

    dotnet build
    dotnet new console -lang F# -o src\Hello	//用new命令新建一个F#语言的控制台程序
    vim src\Hello\Program.fs					//编辑Program.fs文件
    

    此时会发现文件夹src中多了一个Hello文件夹,编辑其中的Program.fs文件

    open System
    open Library	//调用自建的Library
    
    [<EntryPoint>]
    let main argv =
        Say.hello "World"
    

    然后回到命令行运行这个程序

    E:\Documents\00工作文档\0713\>cd src\Hello
    E:\Documents\00工作文档\0713\src\Hello>dotnet run
    Hello World			//输出结果
    

    在F#中,主要通过模块和命名空间来对代码进行组织,而后编译成可执行文件exe或者动态链接库dll。通过dotnet new help命令可以查看我们可以创建的文件类别及其短名称。其中,console为Console Application的缩写,表示命令行应用;classlib为Class Library模板的缩写,为类库。

    展开全文
  • F#语言入门之什么是F#语言

    千次阅读 2018-10-24 19:24:25
    F#是一种函数式编程语言,可以轻松编写正确且可维护的代码。 F#编程主要涉及定义类型推断和自动泛化的类型和函数。 这使您可以将焦点保留在问题域上并操纵其数据,而不是编程的细节。 open System // Gets ...

    F#是一种函数式编程语言,可以轻松编写正确且可维护的代码。

    F#编程主要涉及定义类型推断和自动泛化的类型和函数。 这使您可以将焦点保留在问题域上并操纵其数据,而不是编程的细节。

    open System // Gets access to functionality in System namespace.
    
    // Defines a function that takes a name and produces a greeting.
    let getGreeting name =
        sprintf "Hello, %s! Isn't F# great?" name
    
    [<EntryPoint>]
    let main args =
        // Defines a list of names
        let names = [ "Don"; "Julia"; "Xi" ]
    
        // Prints a greeting for each name!
        names
        |> List.map getGreeting
        |> List.iter (fun greeting -> printfn "%s" greeting)
    
        0

    F#有许多功能,包括:

     

    • 轻量级语法
    • 默认不变
    • 类型推断和自动泛化
    • 一流的功能
    • 强大的数据类型
    • 模式匹配
    • 异步编程

    详细内容查看http://nopapp.com/Blog/Article/FSharp-What-Is-FSharp

    F#语言入门之什么是F#语言

    展开全文
  • 谁在用F#

    千次阅读 2014-03-07 19:36:22
    谁在用F#?   F# 在微软内部表现就很强劲,不仅在微软研究,而且在整个公司。Ralf Herbrich,微软研究院应用项目组的另一位领导,专门从事机器学习技术,是正在逐步壮大的F# 粉丝中一个铁杆。   “第一个应用...

    谁在用F#?

     

    F# 在微软内部表现就很强劲,不仅在微软研究,而且在整个公司。Ralf Herbrich,微软研究院应用项目组的另一位领导,专门从事机器学习技术,是正在逐步壮大的F# 粉丝中一个铁杆。

     

    “第一个应用是解析110GB 大的日志文件,并将其导入SQL 数据库,这些日志文件分布在300 个目录,超过11000 个文本文件。整个应用程序只有90 行(还包括注释),完成解析源文件并导入数据花了不到18个小时,处理速度达到惊人的每秒钟10000 行日志!注意哦,我还根本没有优化代码,只是用了最常见的方法,我真的很惊讶,因为原来打算至少要花一个星期才能完成写代码和导入数据。

    “第二个应用是分析数百万的反馈信息。我已经开发了这个模型的方程,我只是把它当作F#程序输入,从SQL 数据库读数据,结果写入MATLAB 数据文件,加在一起,F# 的源代码只有100行(包括注释)。我再次惊讶于运行时间,处理几百万个数据,只花了10 分钟,还仅是一台普通的桌面机。作为对照,我的C# 程序(以前做的),有1000 行代码,运行也没有这么快。整个任务,从开发模型方程,到完成数据输出,花了两天。”

    Ralf Herbrich 微软研究院

    (http://blogs.msdn.com/dsyme/archive/2006/04/01/566301.aspx)

     

    微软以外的 F# 使用也在迅速增长。我问Chris Barwick 一个问题,他运行一家叫hubFS(http://cs.hubFS.net)的流行网站,专注于 F#,为什么会选择 F# 语言。下面是他的回答:

     

    “我已经从事科学、数学计算超过14年。在此期间,我一直在期待都有这样一个平台,它各方面都应该很强,必须提供有效的工具,工具应该很容易构造,并能有额外的用法,使科学计算环境更加有效。.NET 就是这样平台的代表,它的中间语言提供了跨产品间的一致性,F# 语言有能力在这样平台上进行科学与数学计算。有了这些工具和其他的服务器产品,我的选择扩大了,能够以很低的开发成本,构建复杂系统,并且,以后运行、改进的成本也很低。F# 是高级科学计算的基础。”

     

    Chris Barwick, JJB Research (私人email,这里应该是忘记改了。)

     

    最后,我又问了Chance Coble,软件架构师,F# 能为他的工作带来什么好处:

     

    F# 为我反复创建案例。我决定第一个尝试的 F#项目是机器视觉识别,它可以从提交的指纹卡中标识和提取指纹,加载到生物特征识别系统。该项目计划是进行特工指纹提取,且越来越繁重,能实现自动化就是一个巨大的胜利(用非常少的代码)。后来,我们决定在大项目中引入 F#,

    项目是用C# 写的,并轻松实现集成。从那时起,我在许多项目中使用 F#,比如;机器学习、特定领域语言设计、3D 可视化、符号分析,以及密集数据处理需要考虑性能的任何地方。轻松整合功能模块到现有生产规模应用的能力,使F# 不仅有趣,而且成为项目的重要补充。统一函数式编程具有成熟和丰富的类似.NET 的平台已经提供了一个巨大的机会。

    Chance Coble,Blacklight Solutions公司总建筑师 (私人email)

     

    展开全文
  • 什么是 F#

    千次阅读 2014-03-07 09:43:40
    什么是 F#?   函数编程是解决许多棘手问题的最好方法,但是,纯函数编程并不适合常规编程。因此,函数编程语言逐渐吸收了命令式、面向对象的编程模式,不仅保持了函数编程范式,同时也混合了其他需要的功能,使...

    什么是 F#?

     

    函数编程是解决许多棘手问题的最好方法,但是,纯函数编程并不适合常规编程。因此,函数编程语言逐渐吸收了命令式、面向对象的编程模式,不仅保持了函数编程范式,同时也混合了其他需要的功能,使函数编程编写各种类型的程序都很容易。F# 就是这种尝试的成功代表,比其他函数编程语言做得更多。

    一些流行的函数编程语言,如OCaml、Haskell、Lisp 和Scheme,一直都使用自己的运行时,使程序缺乏互操作性。F# 是一种通用编程语言,使用.NET 的通用运行时,平滑地集成了三种主要的编程模式,这样,可以选择最好、最有效的模式去解决问题。既可以用优函数编程模式、也可以在同一个程序中组合函数、命令、面向对象风格,利用各自的优势。像其他的函数语言一样,F# 也是强类型,而且有智能提示。因此,程序员不需要太多的时间用来打字,除非存在歧义。此外,F# 与.Net 框架的基础类型库(Base Class Library,BCL)无缝集成。在 F# 中使用基础类型库与在 C# 或Visual Basic 中同样简单,甚至更加简单。

    F# 是成功的面向对象的函数编程语言,以 OCaml为模板,并经调整、扩展使之在理论与技术上能很好地和 .Net 相适应,因此,F# 完全包含.Net,.Net 能做的工作它都能做。F# 编译器能编译通用语言基础架构(Common Language Infrastructure,CLI)的所有内容,不用改变任何代码就能支持 .Net 泛型,甚至还有内置的中间代码(Intermediate Language,IL)。F# 编译器不仅能编译任何CLI 程序,还能运行在任何有CLI的环境中,就是说,F# 并不只限于在Windows 环境下运行,还能运行在Linux、Apple Mac OS X、OpenBSD上(第二章将讨论在Linux 上运行F#)。

    F# 编译器随 Visual Studio 2010一起发布,也可以作为Visual Studio 2008 的一个插件。它支持表达式的智能感知和自动检查,以及为表达式提示推断出的类型。这些都有助于语言的使用、推广。

    F# 由剑桥的微软研究院(MicrosoftResearch,MSR)的Don Syme 博士发明的,现在,位于雷德蒙德的微软公司也接受了这个项目,F# 编译器以及与Visual Studio 的集成由两地的小组共同开发。

    虽然还有其他运行在.Net 上的函数编程语言,但F# 已经成为事实上的.Net 函数编程语言,这完全得益于它实现的质量以及与 .NET 和Visual Studio 很好的集成。

    还没有其他的语言像F# 一样容易使用、具有灵活性。

    展开全文
  • fsharp处理Excel数据

    2016-06-04 00:25:30
    1.依赖:Microsoft.Office.Interop.Excel.fsx// Reference the Excel interop assembly #r "Microsoft.Office.Interop.Excel" open Microsoft.Office.Interop// Run Excel as a visible application ...
  • F# Windows应用程序模板

    2011-12-29 15:47:28
    前段时间,我写了一篇描述了如何为WinForms应用程序创建项目模板的博客。这篇博客描述了一个新的项目模板:提供了用F# 创建Windows Service程序需要的元素。你可以在Visual Studio Gallery里找到这个模板: ...
  • Quick Links:Download the F# February 2010 CTP (release info) or VS2010 RC Download the F# October 2009 CTP(release info) Learn F# The F# Language Specification (PDF) MSDN docs for F# (lang
  • F#:微軟的下一代重量級語言

    万次阅读 2008-06-13 13:28:00
    F#:微軟的下一代重量級語言 文 / 蔡學鏞微軟從2002年開始研發F#,2005年推出第一個版本,而2008年的現在,F#已經接近成熟。2007年底,微軟宣布將F#從研究室的專案轉移到產品部門,進入產品化的階段。在下一個版本...
  • F#快速入门资料

    千次阅读 2010-03-20 22:25:00
    The basic syntax of F# - keywords and constructsThe basic syntax of F# - classes, interfaces, and membersThe basic syntax of F# - typesF# function types: fun with tuples and curryingDiscrimi
  • F# 微软的函数式程序设计语言

    千次阅读 2006-05-28 00:18:00
    F#,微软研究院正在研究的一种函数式程序设计语言。其灵感来自于 OCaml。其突出的优势是,与visual Studio 2005 紧密整合。F# 可以与.net 平台的其它语言例如C#,VB.net 相互调用操作。想了解更多关于F#,可以访问...
  • 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起 此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。 输入描述: 输入包括1行字符串,长度不超过100。 输出描述:...
  • shell中的${},##和%%的使用

    万次阅读 2018-06-11 11:22:20
    查看脚本语法是否有错误:bash -n modify_suffix.sh跟踪执行sh -x modify_suffix.sh aaa1.${var} 2.$(cmd) 3.()和{} 4.${var:-string},${var:+string},${var:=string},${var:?string} 5.$((exp)) ...
  • C语言中特殊浮点数:-1.#IND00和NAN

    千次阅读 2017-09-20 15:36:39
    前言在C语言的浮点数:float,double中存在一类特别的数:-1.#IND。我们有时会看到它。比如:float tmp =sqrt(-1); 此时tmp的值就是-1.#INDIND其实就是Implementation Not define的意思,也就是说这个是未定义或者他...
  • 之前写的一个小代码,但只在Windows下有效果: #include &lt;...#define decode(p,r,i,n,t,f) r##f##r##i##t##p #define puts decode(m,s,t,o,e,y) int main() { puts((char*)(double[]){...
  • #if、#if defined、#if !defined、#ifdef、#ifndef、#error

    千次阅读 多人点赞 2016-09-01 16:21:26
    #if,#if defined,#if !defined,#ifdef,#ifndef,#error 宏定义
  • 题目1184:二叉树遍历

    千次阅读 2013-03-07 11:00:07
    题目1184:二叉树遍历 时间限制:1 秒 ...编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以...ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,
  • 迅雷下载破解口令

    千次阅读 2019-01-30 16:21:48
    迅雷电影下载破解口令 #X00c6to1yb7981441# 
  • 根据先序遍历建立一个二叉树

    万次阅读 2017-04-25 23:26:38
    例如如下的先序遍历字符串:ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。输入:输入包括1行字符串,长度不超过100。输出:可能有多组...
  • 【Android UI】色板

    万次阅读 2011-03-10 09:39:00
    Hex CodeColor#FFFFFF #FFFFCC #FFFF99 #FFFF66 #FFFF33 #FFFF00 #FFCCFF #FFCCCC #FFCC99 #FFCC66 #FFCC33 #FFCC00 #FF99FF #FF99CC #FF9999 #FF9966 #FF9933 #FF9900 #FF66FF #FF66CC ...
  • C++ ## 和 #

    千次阅读 2018-11-30 14:15:39
    #define SUITEK_DECLARE_TEST(class_name, attributes) \  public: \  virtual SUITEK_CTestClassInfo* GetTestClassInfo() const; \  static SUITEK_CTest* TestFactory(); \  static void Crea...
1 2 3 4 5 ... 20
收藏数 3,023,731
精华内容 1,209,492
关键字:

f#