F#(1)

如果你也会C#,那不妨了解下F#(1):F# 数据类型

简单介绍

F#(与C#一样,念作“F Sharp”)是一种基于.Net框架的强类型、静态类型的函数式编程语言。
可以说C#是一门包含函数式编程的面向对象编程语言,而F#是一门包含面向对象的函数式编程语言。
可以查看官方文档了解更多信息。

本系列文章假设你在了解C#的情况下,将F#与C#在异同点上进行说明,让读者能快速地对F#有个系统的了解。
才疏学浅,错漏难免,如果您在阅读过程中有什么建议或意见,还请不吝指教。

函数式编程这几年一起不温不火,但相信了解了F#之后,对C#也会有更深的认识,对学习其他函数式语言也会有很容易上手。

Hello, World

在使用F#时,可以像C#一样创建一个控制台项目进行测试。
但因为F#支持以脚本形式运行,所以直接打开F# Interactive(以下简称fsi)进行交互是最方便的。

在Visual Studio中可在“视图-其他窗口”中打开。以前没有csi的时候,一直拿fsi来测试C#代码,在VS2015中终于添加了csi。
如果不想打开臃肿的VS,可在Microsoft SDK的安装位置找到fsi。以下是我安装的F# 4.0的fsi的位置:

"C:\Program Files (x86)\Microsoft SDKs\F#\4.0\Framework\v4.0\Fsi.exe"

介绍任何语言的特有方式就是通过那几乎成为标准的“Hello, World”程序。
F# 输出可使用 printf 函数,如下:

printf "Hello, world!"

当然,也可以像C#一样使用 .Net 的控制台输出函数:

System.Console.Write("Hello World")

当把以上代码敲进fsi里按回车后,会发现并没反应,是因为在fsi里提交代码必须以;;双分号结尾。
请输入 printf "Hello, world!";; 和 System.Console.Write("Hello World");; 或者在换行后输入;;再次回车。
如图:

F#基础类型

下面,我们尝试把以下简单的C#代码转换成F#代码:

int sum = 0;
for (int i = 0; i<=100; i++)
{
    if (i%2 != 0)
        sum += i;
}
Console.WriteLine("0到100中的奇数的和为{0}", sum);

这段命令式代码只是简单地把0到100中的奇数相加,并把和输出。
虽然在C#中也支持函数式,但在这里我们为了了解基本语法,使用简单语句来介绍。

以下是F#版本的代码:

let mutable sum = 0
for i = 0 to 100 do
    if i%2 <> 0 then sum <- sum + i
printfn "0到100中的奇数的和为%A" sum ;;

以上代码在fsi里的运行结果为:

0到100中的奇数的和为2500
val mutable sum : int = 2500
val it : unit = ()

可以看出,F#中每行代码结尾的;是可选的。

因为函数式编程语言的特点之一便是无副作用(No Side Effect)、不可变(Immutable),所以没有变量(Variable)的概念,只有值(Value)的概念。
所以在上面的运行结果中,都是以val开头;而值it默认为最后一次运行结果,在此例中其类型为unit,相当于C#中的void,即无返回值。

但是在很多场景下,Mutable(可变)可以带来很多便利,尤其是在像上面结合命令式编程的场景中。
在上面的代码中,val mutable sum即为一个可变的值。

基础类型

下面将C#和F#的数据类型定义作对比:

数据类型 C# F#
Int int i = 0; let i = 0 
let i = 0l
Uint uint i = 1U; let i = 1u 
let i = 1ul
Decimal decimal d = 1m; let d = 1m 
let d = 1M
Short short c = 2; let c = 2s
Long long l = 5L; let l = 5L
unsigned short ushort c = 6; let c = 6us
unsigned long ulong d = 7UL; let d = 7UL
byte byte by = 86; let by = 86y 
let by = 0b00000101y 
let by = ‘a’B
unsigned byte sbyte sby = 86; let sby = 86uy 
let sby = 0b00000101uy
bool bool b = true; let b = true
double double d = 0.2;
double d = 0 .2d 
double d = 2e-1 
double d = 2 
double d0 = 0
let d = 0.2 
let d = 2e-1 
let d = 2. 
let d0 = 0x0000000000000000LF
float float f = 0.3;
foat f = 0.3f;
float f = 2;
float f0 = 0.0f;
let f = 0.3f 
let f = 0.3F
let f = 2.f 
let f0 = 0x0000000000000000lf
native int IntPtr n = new IntPtr(4); let n = 4n
unsigned native int UIntPtr n = new UIntPtr(4); let n = 4un
char char c = ‘c’; let c = ‘a’
string string str = “abc\n”;
string str = @"c:\filename";
let str = “abc\n” 
let str = @"c:\filename"
big int BigInteger i = new BigInteger(9); let i = 9I

F#的字面量详细介绍可查看MSDN文章

十六进制、八进制和二进制

我们知道,在C#中,可以用0x前缀定义十六进制数值。
而F#中除了十六进制(0x,还可以直接定义八进制(0o)和二进制(0b的数值。

let hex = 0xFABC
let oct = 0o7771L
let bin = 0b00101010y;;

输出结果为:

val hex : int = 64188
val oct : int64 = 4089L
val bin : sbyte = 42y

浮点数

需要注意的是,在F#里,doublefloat都代表双精度浮点数,单精度浮点数称为float32
String还有一个字面量表示方法是三个双引号:

let str = """<book title="Paradise Lost">
    <content />
</book>"""

在使用@为前缀(称为Verbatim String)时,字符串内的若出现双引号必须使用两个双引号转义,使用三个双引号的表示法避免了这个问题。
这种表示法最常用在把XML文档编码到代码文件里。

字节数组

在类型对比表中,byte行可以看到有一个创建字节数组的语法:

let asciiBytes = "abc"B  // val asciiBytes : byte [] = [|97uy; 98uy; 99uy|]

其等价的C#代码是:

byte[] asciiBytes = Encoding.ASCII.GetBytes("abc");

当然,只支持ASCII编码。

变量名

F#的变量名命名规则与C#基本一致,但也可在变量名中包含单引号:

let x = 10
let x‘ = 11
let Tom‘s = "2010"

通过let关键字,将10绑定(赋值)到x,将11绑定到x‘

在C#中,若要将关键字或保留字作为变量名,则可以变量名前加@实现:
例如使用代码

class @class {}

定义一个名为class的类。

在前后加上``即可将任意字符串指定为变量名:

let ``let`` = 4
let ``I love F#`` = "This is an F# program."
(*
    在fsi的输出结果为:
    val let : int = 4
    val ( I love F# ) : string = "This is an F# program."
*)

注意在F#中,单行注释和C#一样使用//,但多行注释使用(* *)

F#的运算符与C#类似,部分区别将在下一篇介绍。感兴趣的可以在fsi里尝试输入运算玩一玩,或许就可以发现区别了。

时间: 2024-11-29 03:00:14

F#(1)的相关文章

设计函数f(f(n))== -n

来源:厦门SEO 我上次面试时遇到的一个问题: 设计一个函数f ,使得: f(f(n)) == -n 其中n是一个32位有符号整数 ; 您不能使用复数算法. 如果您不能为整个数字范围设计这样的函数,请为最大范围设计它. 有任何想法吗? #1楼 x86 asm(AT&T风格): ; input %edi ; output %eax ; clobbered regs: %ecx, %edx f: testl %edi, %edi je .zero movl %edi, %eax movl $1, %

C语言的f(open)函数(文件操作/读写)

头文件:#include <stdio.h> fopen()是一个常用的函数,用来以指定的方式打开文件,其原型为:     FILE * fopen(const char * path, const char * mode); [参数]path为包含了路径的文件名,mode为文件打开方式. mode有以下几种方式: 打开方式 说明 r 以只读方式打开文件,该文件必须存在. r+ 以读/写方式打开文件,该文件必须存在. rb+ 以读/写方式打开一个二进制文件,只允许读/写数据. rt+ 以读/写

计算4000000000以内最大的f(n)=n的值---字符串问题python实现(五)

问题: 写一个函数,计算4 000 000 000 以内的最大的那个f(n)=n的值,函数f的功能是统计所有0到n之间所有含有数字1的数字和.比如:f(13)= 6,因为"1"在"1,2,3,4,5,6,7,8,9,10,11,12,13"中的总数是6(1,10,11,12,13). 分析: 一.简单方法 - 枚举 采用"枚举法"对每个数都计算一遍1的个数,直到枚举完给定范围所有数,找到符合f(n)=n的数.此方法,代码效率极低,运算所需时间巨大

BZOJ 3925: [Zjoi2015]地震后的幻想乡(概率)

CLJ就是喜欢出ctsc上讲的东西,看来还是得找时间把他的那几道题做下 首先记f(x)为答案>x的概率,那么把这个东西从0到1积分就是答案了 f(x)<=>边小于x不能使图联通的概率 这个有点难求,考虑求使图联通的概率 记f(s)为集合s联通的概率,那么f(s)=1-sigma(f(s')*(1-x)^cnt) (s'属于s且s'一定包含某点k,cnt为链接s'与Cs s'的边数) 可以发现f(s)是个多项式,就可以积分了 由于还没用上64位评测系统,double还是不能过,只好用__f

分治法(一)

这篇文章将讨论: 1) 分治策略的思想和理论 2) 几个分治策略的例子:合并排序,快速排序,折半查找,二叉遍历树及其相关特性. 说明:这几个例子在前面都写过了,这里又拿出来,从算法设计的策略的角度把它们放在一起来比较,看看分治是如何实现滴.由于内容太多,我将再花一篇文章来写4个之前没有写过的分治算法:1,大整数乘法   2,矩阵乘法的分治策略   3,最近点对  4,凸包问题,请见下一篇. 好了,切入正题. --------------------------------------------

整体代换(数学)

EG: (x+6)2007+x2007+2x+6=0求x的值. 解: 暴力(限于数感较好的人) 当x=-3是都为零. 好吧.说正解. (x+6)2007+(x+6)=(-x)2007+(-x) 因为f(t)=t2007+t   为奇函数. SO x+6=-x x=-3

(转) 统计在从1到n的正整数中1出现的次数

转自:http://blog.csdn.net/sjf0115/article/details/8600599 问题: 给定一个十进制正整数N,写下从1开始,到N的所有整数,然后数一下其中出现的所有“1”的个数. 例如:N= 2,写下1,2.这样只出现了1个“1”. N= 12,我们会写下1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12.这样,1的个数是5. 问题一: 写一个函数f(N),返回1到N之间出现1的个数,比如f(12)= 5. 解法一: 让我们首先想到的一个

iOS开发UI篇—使用UItableview完成一个简单的QQ好友列表(二)

一.实现效果             二.实现代码 1.数据模型部分 YYQQGroupModel.h文件 1 // 2 // YYQQGroupModel.h 3 // 02-QQ好友列表(基本数据的加载) 4 // 5 // Created by apple on 14-5-31. 6 // Copyright (c) 2014年 itcase. All rights reserved. 7 // 8 9 #import <Foundation/Foundation.h> 10 11 @i

深度学习(上)

深度学习允许由多个处理层组成的计算模型来学习多个抽象层数据的表示.这些方法大大提高了目前最先进的语音识别,可视对象识别,目标检测和其他诸多领域如药物发现和基因组.深度学习发现大数据集结构很复杂,该结构使用BP算法来指示机器应该如何改变内部参数,这些参数是用于从前一层的表示来计算每层的表示.深度卷积网已经在处理图像,视频,语音和音频方面取得了突破,而递归网已经触及到连续数据,如文本和语音. 机器学习技术为现代化社会的许多方面提供了动力:从网络搜索到社交网络上的内容过滤到电子商务网站的推荐,并且越来