F#简明教程二:F#类型系统和类型推断机制

在上一篇教程《F#与函数式编程概述》中我们了解到F#和函数式编程的一些特点,更多关于F#语言和函数式编程的介绍可以参考51CTO之前对微软MVP赵颉老师的专访《TechED 09视频专访:F#与函数式编程语言》。本节教程我们将学习到F#的一些基础原理,在开始之前,让我们先温习一下我们的Hello World代码:

#light

System.Console.WriteLine(“This

is one hello”)

printfn “This

is another hello”

F#是函数式和面向对象的混合体。它有时候会看起来与C#或Visual Basic惊人的相似,但却又完全陌生。F#程序以一系列的表达式形式组成,每个表达式可以通过“let”标识符被指定,比如:

let fles = System.IO.DirectoryInfo(@”C:\Users\Chance”).

GetFiles()

在上面的代码中,“fles”被指定了一个值,在这个例子中,是一个文件路径。有意思的是,程序运行中,直到语句在得到右侧的返回值前,“fles”的实际类型都没有被详细定义。你可能觉得有些别扭,在Java或其他编程语言中,变量fles应该被定义成一种数据类型,string或是其他什么类型以在内存中可以明确的被编译器区别对待,但这些规则在F#中有些不同。这也导致我们的F#简明教程稍有不同,我们不会像通常的教程那样介绍F#的基本数据类型,从某种意义上说,F#可以是任意类型或只有一个类型。

F#小提示:F#是一种类型推断语言,它们在编译过程中被推断和确定。如果你在VisualStudio中编写F#,将鼠标指向某个值就会得到它的类型,编译器可以通过函数体或其他方式的定义推断出类型;VisualStudio是开发F#的主要工具,51CTO推荐您阅读Visual Studio 2010中关于F#的资源一文。

类型推断(Type Inference)我们说数据的类型是被推断出的,因为F#的编译期进程会试图根据变量自身的特点来判断出它的类型并确保这种类型是安全的。尽管F#是强类型语言,但变量的类型声明在类型的判断推理过程中并不是必须的。

类型推断有自身的优点。在使用F#开发一些大型应用时,比如.NET和Java开发者都很熟悉的泛型特性(Generics)便是由类型推断来完成。注意,F#编译器会视任何没有类型标注的表达式为泛型。例如,下面的函数中,各变量的类型被定义(推断为)泛型,即使程序编写者没有定义任何类型。

let f x =

let y = g x

h y

let f (x:’a) : ’b =

let y:’c = (g:’a->’c) x

(h:’c->’b) y

F#小提示:在F#中,泛型类型参数是一个以撇号为前缀的字符。比如上面例子中的’b和’c就是最常用的泛型参数。像在.NET中一样,泛型类型也可使用尖括号语法,比如“Dictionary<’Key,’Value>”。只有一个泛型参数的时候,你有时候会看到它使用‘前缀’语法而不是尖括号——最常见的是和F#泛型类‘list’和‘option’一起使用。比如“intlist”和“list<int>”表达同一种功能,只是书写方式不同。

F#类型推断机制

F#语言中的大多数类型推断可以遵循以下两条规则。首先,如果一个函数用于产生一个值,编译器将假定该值的类型是函数需求的。第二,如果一个值是一个表达式的必然结果,这个值的类型是这个表达式所决定的。

有些情况下这些简单的规则不够完全,编译器必须需要类型声明。比如,当一个算数运算符被使用,F#会处理的非常谨慎,如果没有程序员的明确代码,不会将一个数值型赋予另一个。这样做是为了确保F#在进行大规模数值计算时,类型推断不会加重编译器的负担。

针对第二条规则的例子在方法过载的情况下发生。比如Write方法在System.Console(.NET中System.Console封装了基于控制台应用程序的输入、输出和错误流操作)中有18个负载。类型推断可以确定传送给它的类型,但是无法确定另一个方向传送的值的类型。

类型推断不只是简单的符号,它还可以用于程序功能的检测。当你写了一段代码,类型推断功能为这些代码智能的获得了指定的类型,这意味着错误不会被引入程序。这种机制使F#获得动态语言的代码简洁性的同时保证了完全静态的类型系统。

更多关于F#的类型和语法基础请参考:

◆ F#数据类型:Discriminator Union

◆ F#基本语法,模式匹配及List

F#的类型系统和类型推断机制是学习和理解F#语言的基础,掌握了这些有利于我们之后的学习。下周我们将继续F#的学习,一起探究F#的基础语法。

时间: 2025-01-01 20:16:03

F#简明教程二:F#类型系统和类型推断机制的相关文章

Dreamweaver 4 简明教程(二、初步认识 Dreamweaver)

dreamweaver|教程 二.初步认识 Dreamweaver Dreamweaver的启动 Dreamweaver的安装过程非常简单,一但成功安装后,就可以在开始菜单找到Dreamweaver的选项: 编辑窗口 第一次启动Dreamweaver,首先看到的是Dreamweaver的编辑窗口,千万别给上面密密麻麻的浮动窗口吓倒,其实常用的,就以下几个: ① 主菜单:在这里可以找到编辑窗口的的绝大部分功能: ② 工具栏:是Dreamweaver4的新增功能: ③ 对象面板(Objects):在

C#简明教程二

教程 第二节:读取命令行输入 许多程序可以接受命令行输入,下面的程序就是接受命令行的输入后,再把它打印到控制台屏幕上. 程序1-2:NamedWelcome.cs // Namespace Declaration using System; // Program start class class NamedWelcome { // Main begins program execution. public static void Main(string[] args) { // Write t

c语言-error C2371: “f”: 重定义;不同的基类型 求助

问题描述 error C2371: "f": 重定义:不同的基类型 求助 #include<stdio.h> main() { int a,b,c,d; a=4;b=3; f(a,b,&c,&d); printf("%d ",c+d); } void f(int x,int y, int *cp, int *dp) { *cp=x+y; *dp=x-y; return; } 代码如上时,程序报错,"重定义.不同的基类型"

Android简明开发教程二十二:使用资源Resources

在前面的例子中,我们忽略了一个重要的原则,在代码和Layout中,直接使用了字符串常量,比如: <Button android:text="Pattern" android:id="@+id/btnPattern" android:layout_width="wrap_content" android:textColor="@color/black" android:checked="true" an

F#简明教程一:F#与函数式编程概述

F#是微软.NET开发平台的一门编程语言,其最大的特点是对函数式编程(FP,FunctionalProgramming)的引入:F#对面向对象(OOP)编程的支持也很出色,使用F#语言,开发人员可以自由选择函数式编程或面向对象编程来实现他们的项目.此外,F#还可以与.NET平台上C#.VB等其他编程语言紧密结合. CPU多核心化和云计算的背景下,函数式编程可以很好的解决多并发运算的问题(在处理并发问题方面,面向对象编程存在一定程度的固有缺陷,比如类和实例化过程中产生的一些副作用,详细请参考51C

Java 8简明教程

原文地址 本文由 ImportNew - 黄小非 翻译自 winterbe.欢迎加入翻译小组.转载请见文末要求. ImportNew注:有兴趣第一时间学习Java 8的Java开发者,欢迎围观<征集参与Java 8原创系列文章作者>. 以下是<Java 8简明教程>的正文. "Java并没有没落,人们很快就会发现这一点" 欢迎阅读我编写的Java 8介绍.本教程将带领你一步一步地认识这门语言的新特性.通过简单明了的代码示例,你将会学习到如何使用默认接口方法,La

基于LLVM的编译原理简明教程 (1) - 写编译器越来越容易了

基于LLVM的编译原理简明教程 (1) - 写编译器越来越容易了 进入21世纪,新的编程语言如雨后春笋一样不停地冒出来.需求当然是重要的驱动力量,但是在其中起了重要作用的就是工具链的改善. 2000年,UIUC的Chris Lattner主持开发了一套称为LLVM(Low Level Virtual Machine)的编译器工具库套件.后来,LLVM的scope越来越大,Low Level Virtual Machine已经不足以表示LLVM的全部,于是,LLVM就变成了正式的名字.LLVM可以

Linux LVM简明教程

Linux LVM简明教程 逻辑卷管理LVM是一个多才多艺的硬盘系统工具.无论在Linux或者其他类似的系统,都是非常的好用.传统分区使用固定大小分区,重新调整大小十分麻烦.但是,LVM可以创建和管理"逻辑"卷,而不是直接使用物理硬盘.可以让管理员弹性的管理逻辑卷的扩大缩小,操作简单,而不损坏已存储的数据.可以随意将新的硬盘添加到LVM,以直接扩展已经存在的逻辑卷.LVM并不需要重启就可以让内核知道分区的存在. LVM使用分层结构,如下图所示. 图中顶部,首先是实际的物理磁盘及其划分的

perl 简明教程 perl教程集合_perl

参考:http://shouce.jb51.net/perl5/ 网站环境配置:http://www.jb51.net/article/74005.htm Perl的基本语法 http://www.jb51.net/shouce/Perl.htm 前言:perl是什么,干什么用的?perl原来设计者的意图是用来处理 字符的,80%的强项是处理字符,当然其它的很多都可以.现在很多网页也是用perl的,通常需要CGI环境,比如 $char =~ /语言/ ,意思是查找含有"语言"这两个字的