F#和C#的语法差别

语法上,F#和C#有两个主要差别:

  • 用缩进而非花括号分隔代码块
  • 用空白而非逗号分隔参数

F#常见语法元素

以下是F#代码中常见的语法元素

注释

// 这是单行注释
(* 这是多行注释
第二行
最后一行 *)

let 绑定

let myInt =
let myFloat = 3.14
let myString = "hello"

上面的语句没有显式指定 myInt, myFloat, myString 的类型,类型由编译器推断。

列表

let twoToFive = [;;;]        // 方括号表示列表,元素用分号分隔
let oneToFive = :: twoToFive // 符号 :: 将值添加到列表头部,得到新列表,结果为 [1;2;3;4;5]
let zeroToFive = [;] @ twoToFive // 符号 @ 连接两个列表,得到新列表,结果为 [0;1;2;3;4;5]

务必注意,列表元素使用分号分隔,而非逗号分隔。

函数

命名函数用 let 关键字定义,匿名函数用 fun 关键字定义。

let square x = x * x          // 使用 let 定义命名函数,函数形参不用小括号围住
square // 运行函数,实参也没有小括号 let add x y = x + y // 不可使用 (x,y)
add // 运行函数 // 多行函数,用缩进,不用分号
let evens list =
let isEven x = x% = // 内部函数
List.filter isEven list // List.filter 是库函数 evens oneToFive // 运行函数 // 用小括号指明优先级
let sumOfSquaresTo100 =
List.sum (List.map square [..]) // 如果没有小括号,那么 List.map 会是 List.sum 的参数 // 管道 |>,将操作的输出传给下一个操作
let sumOfSquaresTo100piped =
[..] |> List.map square |> List.sum // 用 fun 关键字定义拉姆达(匿名函数)
let sumOfSquaresTo100withFun =
[..] |> List.map (fun x->x*x) |> List.sum

模式匹配

match..with 用于模式匹配

// 类似于 switch/case
let simplePatternMatch =
let x = "a"
match x with
| "a" -> printfn "x is a"
| "b" -> printfn "x is b"
| _ -> printfn "x is something else" // 下划线匹配任意值 // Some(..) 和 None 有点像可空类型(Nullable)
let validValue = Some()
let invalidValue = None // match..with 匹配 "Some" 和 "None",同时从 Some 中取出值
let optionPatternMatch input =
match input with
| Some i -> printfn "input is an int=%d" i
| None -> printfn "input is missing" optionPatternMatch validValue
optionPatternMatch invalidValue

复杂类型

复杂类型是指元组,记录和联合

// 元组,包含有序但未命名的值,值之间用逗号分隔
let twoTuple = ,2 // 二元组
let threeTuple = "a",,true // 三元组 // 记录,包含命名的字段,字段之间用分号分隔
type Person = {First:string; Last:string}
let person1 = {First="john"; Last="Doe"} // 联合,包含选项,选项之间用竖线分隔
type Temp =
| DegreesC of float
| DegreesF of float
let temp = DegreesF 98.6 // 类型可以递归的组合,例如,下面的 Employee 联合包含 Employee 类型的列表
type Employee =
| Worker of Person
| Manager of Employee list
let jdoe = {First="John";Last="Doe"}
let worker = Worker jdoe

格式化输出

printf 和 printfn 向控制台输出,类似于 C# Console 类的 Write 和 WriteLine 方法。sprintf 输出到字符串,类似于 String 类的 Format 方法。

printfn "Printing an int %i, a float %f, a bool %b"  2.0 true
printfn "A string %s, and something generic %A" "hello" [;;;] // 复杂类型具有内置的美观输出格式
printfn "twoTuple=%A,\nPerson=%A,\nTemp=%A,\nEmployee=%A" twoTuple person1 temp worker let str1 = sprintf "Printing an int %i, a float %f, a bool %b" 2.0 true
let str2 = sprintf "A string %s, and something generic %A" "hello" [;;;]

比较F#和C#:计算平方和

C#版,不使用 linq

public static class SumOfSquaresHelper
{
public static int Square(int i)
{
return i * i;
} public static int SumOfSquares(int n)
{
int sum = ;
for (int i = ; i <= n; i++)
{
sum += Square(i);
}
return sum;
}
}

F#版

let square x = x * x
let sumOfSquares n =
[..n] // 创建 1 到 n 的列表
|> List.map square // 对每个元素求平方,得到新列表
|> List.sum // 将平方列表求和

F# 语法噪音小,没有花括号,分号,并且在这里不需要显式指定类型。

C#版,使用 linq

public static class FunctionalSumOfSquaresHelper
{
public static int SumOfSquares(int n)
{
return Enumerable.Range(, n)
.Select(i => i * i)
.Sum();
}
}

使用 linq 改写的 C# 代码简洁很多,但不能消除语法噪音,参数和返回值的类型也是必须的,仍然不如 F# 版简洁。

例子:快速排序算法

快速排序算法的步骤是:

  1. 从列表中取出一个数作为基准
  2. 将小于基准的数放在左边,不小于基准的数放在右边
  3. 对基准两边的部分进行快速排序

下面是 F# 实现快速排序的例子

let rec quicksort list =
match list with
| [] -> []
| firstElem::otherElements ->
// 小于第一个元素的元素
let smallerElements =
otherElements
|> List.filter (fun e -> e < firstElem)
|> quicksort // 不小于第一个元素的元素
let largerElements =
otherElements
|> List.filter (fun e -> e >= firstElem)
|> quicksort // 连接成新列表
List.concat [smallerElements; [firstElem]; largerElements] printfn "%A" (quicksort [;;;;;;])

如果应用库函数和一些技巧,代码可压缩成:

let rec quicksort = function
| [] -> []
| first::rest ->
let smaller,larger = List.partition ((>=) first) rest
List.concat [quicksort smaller; [first]; quicksort2 larger]

参考网站:http://fsharpforfunandprofit.com/

F# 语法概览的更多相关文章

  1. 《Go并发编程实战》读书笔记-语法概览

    <Go并发编程实战>读书笔记-语法概览 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客我们会快速浏览一下Go的语法,内容涉及基本构成要素(比如标识符,关键字,子 ...

  2. ES6新语法概览

    简介 ES6是JavaScript语言的新一代标准,加入了一些新的功能和语法,正式发布于2015年6月,亦称ES2015:该标准由ECMA(欧洲计算机制造联合会)的第39号技术专家委员会(TC39)制 ...

  3. 【Scala】新手入门,基础语法概览

    目录 变量.常量和数据类型 var val 数据类型 条件表达式 块表达式 to循环 for循环 for推导式 scala中的方法和函数 方法的定义 函数的定义 函数和方法的区别 变量.常量和数据类型 ...

  4. ES6新语法

    ES6新语法概览 简介 ES6是JavaScript语言的新一代标准,加入了一些新的功能和语法,正式发布于2015年6月,亦称ES2015:该标准由ECMA(欧洲计算机制造联合会)的第39号技术专家委 ...

  5. F#周报2019年第25期

    新闻 Azure Notebook概览 SpecFlow 3就在这里了! 使用新的Try .NET模版创建交互式文档 逐渐演化的.NET Core框架 Dylan与Linebreakers Oslo ...

  6. [Oracle] 分析功能(1)- 语法

    语法概览 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGJhbm90ZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQ ...

  7. 函数式编程之-初窥F#

    大量讲解函数式编程语言的书籍最终都会用Fuctor,Monad,Monoids,范畴论等各种词汇吓退命令式语言玩家,所以我试图避开这些问题,揭开这些复杂词汇带来的具有实战意义的成果.另外我会尽量使用C ...

  8. F#周报2019年第44期

    新闻 Elmish.WPF教程 介绍Orleans 3.0 GC配置历史 介绍ONNX运行时1.0 介绍微软Q&A(预览) 使用App中心持续布署与监控你的UWP,WPF与Windows Fo ...

  9. 20155331 2016-2017-2 《Java程序设计》第七周学习总结

    20155331 2016-2017-2 <Java程序设计>第七周学习总结 教材学习内容总结 一.认识Lambda语法 1.Lambda语法概览 Arrays的sort()方法可以用来排 ...

随机推荐

  1. swift webView的高度自适应内容

    废话不多 直接上代码 //在webView的协议方法里实现以下代码 func webViewDidFinishLoad(webView: UIWebView) {//加载完成 //        se ...

  2. 我用Cocos2d-x模拟《Love Live!学院偶像祭》的Live场景(三)

    [前言和思路整理] 千呼万唤Shi出来啊(好像也没人呼唤),最近公司项目紧,闲暇时间少更得慢,请见谅. 上一章我们分析并实现了打击物件类BeatObject,和它的父节点BeatObjectColum ...

  3. GCD教程(一):基本概念

    在网上看到关于GCD的一个很不错的教程,这里做一下转载 原帖地址:http://www.dreamingwish.com/dream-2012/of-of-of-of-gcd-introduced-1 ...

  4. jenkins用户权限配置错误,导致登录时提示:没有Overall/read权限

    jenkins用户权限配置错误,导致登录时提示:没有Overall/read权限 由于初次接触jenkins,于是在搭建好jenkins以后,想要对用户进行管理,于是乎开始在系统管理->conf ...

  5. jQuery基本过滤选择器

    jQuery基本过滤选择器: <h1>this is h1</h1> <div id="p1"> <h2>this is h2< ...

  6. JSP EL表达式 获得 request的GET/POST方法

    JSP EL表达式 获得 request的GET/POST方法: 不在requestScopse中: <p>得到request的方法</p> <p>pageCont ...

  7. HTML5 & CSS3初学者指南(3) – HTML5新特性

    介绍 本文介绍了 HTML5 的一些新特性.主要包含以下几个方面: Web 存储 地理位置 拖放 服务器发送事件 Web存储 HTML5 Web 存储的设计与构想是一个更好的机制来存储客户端的网络数据 ...

  8. 这个发现是否会是RSA算法的BUG、或者可能存在的破解方式?

    笔者从事各种数据加解密算法相关的工作若干年,今天要说的是基于大数分解难题的RSA算法,可能有些啰嗦. 事情的起因是这样的,我最近针对一款芯片进行RSA CRT解密的性能优化.因为期望值是1024bit ...

  9. ConcurrentHashMap原理

    转载地址:http://www.blogjava.net/xylz/archive/2010/07/20/326661.html 在上一篇中介绍了HashMap的原理,这一节是ConcurrentMa ...

  10. tbl.js div实现的表格控件,完全免费,不依赖jquery

    html上现在有比较好用的表格控件是datatable,但是编辑.按钮等部分是收费的,只有基础功能免费.而且尺寸发生变化时需要手工刷新等繁琐操作较多.所以我开发一个免费的供大家使用. 本项目已用于&q ...