【F#初学者】第一讲 F#简介&&&第一个F#程序

这个系列将会讲述,关于F#本身的语法,功能等相关知识。作为另一个【函数式编程】系列的知识补充

【C#/F#】「函数式编程」第一讲:高阶函数、纯函数

我们开门见山,以几个问题作为开端,解答读者可能想知道问题。

为什么要选择F#?

编程语言重要吗?

或许大学老师会告诉你,编程语言只是工具,只取决于你怎么用它。这么说也没错,本质上我们都是告诉计算机要做什么。事实上,编程语言之间确实有很多共通之处,在最初学习编程时,这句话或许没什么问题。但为什么有这么多的编程语言呢?既然是工具,当然有好不好用,适不适合用之分了。最初我们只需要纯粹的逻辑时,语言本身特性就显得不关键了,但当我们步入更复杂的领域后...

编程语言很重要,一个编程语言会很可能影响编写的代码的可靠性、安全性和效率,也会影响可读性,重构难易度等等。同时,了解一门编程语言,即使后续不再会使用它,也可能使你受益匪浅。而F#正是这样一种语言。


如果读者没有了解过函数式编程,而是抱着再学习一门类似C#,或是C++这类偏重于面向对象的语言的想法的话。那么在正式开始之前必须转变你的想法,我们是在学习一个全新的东西,对于面向对象程序员来说,这是一个打破常规的新东西。尽管F#也支持面向对象编程,但这不是他的强项,也不是他希望你使用的。

F#更偏向于使用函数式编程的代码,使用它,你就可以获得更具可读性,安全,易于测试,易于并行的代码。在这个基础上,你还能享受到.NET生态中几乎所有的好处,这点与C#一样。他强大的类型推断系统也能让我们更容易编写出简洁清晰的代码

对我来说,我选择F#的原因是它是一门运行在.NET之上的(强类型)函数式语言,并且我能通过F#学习到更多的新知识。我喜欢.NET,也喜欢新的知识,这对我而言再适合不过。

我能用F#做什么?

F#与C#都是.NET家族中的一员,F#作为C#的扩展使用非常方便,配合languageExt库使用,也能获得更好的体验。当然F#中也可以轻松的使用C#的库,不过F#的项目模板相对没有C#那么丰富,个人来说更喜欢将F#库集成到C#中使用。

  • F#的特性让你能够写出更加健壮的代码,你能够轻松的写出更少出现bug的代码。

  • F#可以更好的处理异步/并行等任务

  • F#可以编译成JavaScript的代码使用

  • 并且,F#的学习可以让你在其他领域也获得不少新思路。

  • F#作为函数式编程的入门语言,也是一个非常好的选择

怎么用F#?

F#目前包含在.NET中,与C#/VB.NET有相同的地位,只需要浏览器访问get.dot.net,安装.NET SDK之后,就可以使用了。

F#可以和正常项目一样开发,也可以使用dotnet fsi指令进入交互窗口测试使用。同样的,也可以使用jupyter notebook进行编写

交互窗口

jupyter notebook

推荐使用什么编写?

VSCode, Rider, Visual Studio都可以用来编写F#,不过我首选推荐的是VSCode(配合插件Ionide for F#(此插件包含在.NET扩展包中)),Rider和VS体验类似,Rider个人体验相对更好一些

开始我们第一个F#的程序

首先,一切的开始,最简单的Hello World

printfn "Hello From F#!"

然后是我们F#中声明”变量“的方法

let a = 1

值得注意的是F#中默认数据是不可变的,所以我们无法使用 a = 2 对a赋值。如果要声明一个变量是可变的话,需要显式的标记为mutable.(但通常情况下 我们不推荐这么做)

let mutable x = 10
x <- 3

接下来是我们的 "分支语句"(if)

if a = 1 then
    printfn "a is 1"
elif a = 2 then
    printfn "a is 2"
else
    printfn "a is neither 1 nor 2"

C#有所不同,但看起来功能差异不大。但其实二者完全不一样,F#里一切皆为表达式,不过我们先搁置这个

接下来是我们的“循环语句”(while for)

for i in 1..5 do
    printfn "i is %d" i
while true do
    printfn "a is %d" a

与if一样,在F#中这二者也是表达式,也没有常规语言中的continue或是break来控制循环。事实上在F#中,我们不推荐使用for和while来执行任务,这两者更偏向于命令式,去精细的控制流程。而我们F#(函数式编程),有另一种方式去执行类似的事务,不过还是一样,这里暂且搁置。

最后一块拼图则是我们的函数

let f a b = a + b
let f1() = 1
let f3 (a: int) (b: int) : int = a + b

以上定义了三个函数, 第一个函数的参数在使用时会自动类型推断,当然,也可以使用第三个函数的声明方法,更准确的声明函数签名

第二个函数没有任何入参 所以需要加上一对括号表明这是一个没有入参的函数,不过事实上,在F#中,我们很少会用到完全没有入参的函数。

最后,结合上面所提到的内容,我们可以正式开始编写一个程序。通过身高体重计算出我们的BMI值,并输出健康或者肥胖与偏瘦。

定义BMI值为 体重/(身高^2),当值小于18.5时为偏瘦,在18.5到24之间则为正常,在24到28之间为过重,28以上则是肥胖。

根据以上定义和要求,我们可以轻松的写出我们的代码

let printfBmi (weight: float) (height: float) = 
    let bmi = weight / (height * height)
    if bmi < 18.5 then printfn "偏瘦"
    elif bmi < 24.0 then printfn "正常"
    elif bmi < 28.0 then printfn "过重"
    else printfn "肥胖"
printfBmi 70.0 1.75

so easy! 看起来没有任何问题。不过,这其实不符合我们F#的风格,这个函数中有着太多的副作用,让我们函数式编程者看的头疼

忍不了了,现在我们稍微对代码进行改动

let getBmiResult (weight: float) (height: float) = 
    let bmi = weight / (height * height)
    if bmi < 18.5 then "偏瘦"
    elif bmi < 24.0 then "正常"
    elif bmi < 28.0 then  "过重"
    else "肥胖"
printfn "%A" (getBmiResult 70.0 1.75)

我们修改了函数,让他返回一个值而不是输出一个值,这时候,这个函数就完全没有了副作用(IO),并且也拥有了一个有意义的返回值(原来的函数也拥有返回值(unit), 并不像返回类型是void那样的函数,我们可以将unit绑定到一个标识符上)

let v = printfn "Hello World" //读者可以在交互窗口测试这段代码
printfn "%A" v

这样就得到了一个符合F#风格的程序,可能读者还对这种微妙的变化没有什么特别的感受,但在后续的学习中,我们越来越明白这种改动所带来的好处。

Bilibili: @无聊的年 【F#入门】认识F#与第一个F#程序

微信公众号: @scixing的炼丹房

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值