F#奇妙游(1):F#浅尝
F#奇妙游(1):F#浅尝
是什么
F#是.NET平台的OCaml。
这句话很欠打,.NET和OCaml前者知道的人有一些,后者就很少了。.NET平台是一个开源的软件平台,早期由微软主导,目前已经开源,由.NET基金会维护。
OCaml是一种函数式编程语言,它的类型系统非常强大,支持多态、类型推断、类型参数化等特性。有很多编译器早期都是利用OCaml实现的,比如LLVM,Rust等。OCaml也是一个不纯的函数式语言,它支持面向对象编程、命令式编程等多种编程范式。
F#是OCaml的一个子集,它的语法和OCaml不能说非常相似,只能说完全相同。它的类型系统为适应.NET平台进行了大量改造,可以完全应用与.NET平台的各类开发活动。
为什么
为什么要学习F#,这个问题的答案有很多,我自己的理由非常简单:
- 语言本身非常有趣(最重要的是fan-base几乎不存在,不会惹人讨厌)
- .NET平台很有前途(并不是,划掉)
如果要按照语言警察和语言使徒开展传教活动的惯例,需要列一列语言的主要特征:
- 强类型/静态类型,支持类型推断和类型参数化
- 可编译,提供交互式环境
- 模式匹配
- 异步、并发
- 并非纯函数式语言,多范式
- 函数式编程
- 响应式
- 高阶函数,函数组合
- 面向对象编程
- 命令式编程
- 泛型编程
- 元编程
- 函数式编程
怎么做
安装
F#是.NET平台的一部分,所以安装.NET Core SDK就可以了。比如在Windows上,可以从这里下载安装包。安装7.0、8.0-preview什么的都行。
安装完成后,可以在命令行中输入dotnet --version
来检查是否安装成功。然后能使用dotnet
命令来创建F#项目,启动交互式环境等。运行dotnet --help
就能看到所有的命令。MSDN提供了一个入门教程。这个教程有中文版,但是翻译的很烂,建议看英文版。
交互式环境
F#提供了一个交互式环境,可以在其中编写F#代码,然后立即执行。这个环境叫做F# Interactive,简称F# REPL。
dotnet fsi
来个Hello World,编辑一个文件,比如hello.fsx
,然后在文件中输入:
printfn "Hello World"
然后在命令行中输入:
dotnet fsi hello.fsx
就能看到输出了。
奇妙游
普普通通的dotnet new console -lang F# -o HelloWorld
就能创建一个F#的控制台项目。然后切换到Helloworld
目录再运行dotnet run
就OK。但是这么普普通通的项目没什么意思,我们来做点有意思的事情。
我们新建一个工程文件, winformfsharp.fsproj,内容如下:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net7.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<PublishSelfContained>false</PublishSelfContained>
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>
</Project>
然后新建一个文件,Program.fs,内容如下:
open System
open System.Windows.Forms
open System.Drawing
module MainForm =
// 自定义操作符||>,用于简化代码
let inline (||>) x f =
f x
x
// 定义输入文字的控件
let edit = new TextBox(Text = "World", Dock = DockStyle.Fill)
let getGreeting msg = $"Hello, %s{edit.Text} %s{msg}!"
// 定义按钮控件
let button =
new Button(Text = "Click Me!", Dock = DockStyle.Fill)
// 定义输出文字的控件
let textArea =
new TextBox(Text = "Hello, World!", Multiline = true, Dock = DockStyle.Fill, ReadOnly = true)
||> fun t ->
button.Click.Add(fun _ ->
t.Text <- t.Text + Environment.NewLine + getGreeting "from F#"
t.ScrollBars <- ScrollBars.Both
t.Select (t.TextLength, 0)
t.ScrollToCaret ()
)
// 自定义的操作符||>,设置事件函数,返回对象
// 定义布局
let layout =
new TableLayoutPanel(Dock = DockStyle.Fill, ColumnCount = 2, RowCount = 2)
||> fun l ->
l.Controls.Add(edit, 0, 0)
l.Controls.Add(button, 1, 0)
l.Controls.Add(textArea, 0, 1)
l.SetColumnSpan(textArea, 2)
l.PerformLayout()
// 定义窗口
let form =
new Form(
Text = "F# Form!",
Width = 300,
Height = 200,
StartPosition = FormStartPosition.CenterScreen,
Font = new Font("Consolas", 12.0f, FontStyle.Regular, GraphicsUnit.Point, byte 0uy),
MaximizeBox = false,
MinimizeBox = false,
AcceptButton = button
)
||> fun f -> f.Controls.Add(layout)
// 定义入口
[<EntryPoint>]
[<STAThread>]
let main argv =
Application.EnableVisualStyles()
Application.Run(form)
0
然后在命令行中运行dotnet run
,就能看到一个窗口了。
总结
- F#是一门非常有趣的语言,可以用来做很多事情。
- F#的语法非常简洁别扭,但是有时候也会让人摸不着头脑。
- F#的类型系统非常强大,但是有时候也会让人摸不着头脑。
- F#的类型推断非常强大,但是有时候也会让人摸不着头脑。
我的头早就被摸秃了,所以我喜欢F#。