F# 语法概览
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# 版简洁。
例子:快速排序算法
快速排序算法的步骤是:
- 从列表中取出一个数作为基准
- 将小于基准的数放在左边,不小于基准的数放在右边
- 对基准两边的部分进行快速排序
下面是 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# 语法概览的更多相关文章
- 《Go并发编程实战》读书笔记-语法概览
<Go并发编程实战>读书笔记-语法概览 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客我们会快速浏览一下Go的语法,内容涉及基本构成要素(比如标识符,关键字,子 ...
- ES6新语法概览
简介 ES6是JavaScript语言的新一代标准,加入了一些新的功能和语法,正式发布于2015年6月,亦称ES2015:该标准由ECMA(欧洲计算机制造联合会)的第39号技术专家委员会(TC39)制 ...
- 【Scala】新手入门,基础语法概览
目录 变量.常量和数据类型 var val 数据类型 条件表达式 块表达式 to循环 for循环 for推导式 scala中的方法和函数 方法的定义 函数的定义 函数和方法的区别 变量.常量和数据类型 ...
- ES6新语法
ES6新语法概览 简介 ES6是JavaScript语言的新一代标准,加入了一些新的功能和语法,正式发布于2015年6月,亦称ES2015:该标准由ECMA(欧洲计算机制造联合会)的第39号技术专家委 ...
- F#周报2019年第25期
新闻 Azure Notebook概览 SpecFlow 3就在这里了! 使用新的Try .NET模版创建交互式文档 逐渐演化的.NET Core框架 Dylan与Linebreakers Oslo ...
- [Oracle] 分析功能(1)- 语法
语法概览 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGJhbm90ZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQ ...
- 函数式编程之-初窥F#
大量讲解函数式编程语言的书籍最终都会用Fuctor,Monad,Monoids,范畴论等各种词汇吓退命令式语言玩家,所以我试图避开这些问题,揭开这些复杂词汇带来的具有实战意义的成果.另外我会尽量使用C ...
- F#周报2019年第44期
新闻 Elmish.WPF教程 介绍Orleans 3.0 GC配置历史 介绍ONNX运行时1.0 介绍微软Q&A(预览) 使用App中心持续布署与监控你的UWP,WPF与Windows Fo ...
- 20155331 2016-2017-2 《Java程序设计》第七周学习总结
20155331 2016-2017-2 <Java程序设计>第七周学习总结 教材学习内容总结 一.认识Lambda语法 1.Lambda语法概览 Arrays的sort()方法可以用来排 ...
随机推荐
- OGG数据仓库以及单向复制(二)
Configure Extract(提取) Process in Source system 配置capture(捕获)参数 Edit extract process parameter G ...
- Camera.ScreenPointToRay 解析
Unity官方文档: Camera.ScreenPointToRay public function ScreenPointToRay(position: Vector3): Ray; Descrip ...
- (转)java生成UUID通用唯一识别码 (Universally Unique Identifier)
(原文链接:http://blog.csdn.net/carefree31441/article/details/3998553) UUID含义是通用唯一识别码 (Universally Uniq ...
- html标签大全(1)
http标签详解及讲解 1.基础标签 <!DOCTYPE html> <!--表示文本类型--> <html> <!--<html> ...
- 排查问题所用到的一些Linux命令实践(不定期更新。。)
一.前言 线上问题排查可能是每个程序员都会经历的.在排查的过程中,往往会用到很多Linux命令,也会产生一些很实用的技巧.本博文通过分析一次线上问题排查的过程,把所有用到的命令串起来.每个Linux命 ...
- 用Spark学习FP Tree算法和PrefixSpan算法
在FP Tree算法原理总结和PrefixSpan算法原理总结中,我们对FP Tree和PrefixSpan这两种关联算法的原理做了总结,这里就从实践的角度介绍如何使用这两个算法.由于scikit-l ...
- HDU5914
Triangle Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Su ...
- JTable 的使用
JTable是Swing编程中的一种控件. 一.创建表格控件的各种方式:1) 调用无参构造函数. JTable table = new JTable(); 2) 以表头和表数据创建表格. Object ...
- 如何编写一个gulp插件
很久以前,我们在"细说gulp"随笔中,以压缩JavaScript为例,详细地讲解了如何利用gulp来完成前端自动化. 再来短暂回顾下,当时除了借助gulp之外,我们还利用了第三方 ...
- uml系列(七)——交互图
交互图是uml中描述系统中的对象如何进行交互动作的 . 废话不多说,还是来张图: 概念 交互图,主要描述的是系统中的一组对象的消息的传递的,为对象间的交互定义了一个可视的表示方法. ...