6.6.1 F# 中函数调用的类型推断

虽然,在 F# 中可以用尖括号指定类型参数值,与 C# 中的方式相同,但这种方法很少使用。原因是,当编译器无法推断出所有的信息,需要程序员的帮助时,我们仅在真正需要的地方,添加类型批注。我们用一个示例来演示:

> Option.map (fun dt -> dt.Year)(Some(DateTime.Now));;

error FS0072: Lookup on object ofindeterminate type.

> Option.map (fun (dt:DateTime) ->dt.Year) (Some(DateTime.Now));;

val it : int option = Some(2008)

与 C# 不一样,F# 中参数值的顺序很重要,因此,第一种情况会失败。这是因为F# 编译器要遇到第二个参数值时,才知道 dt 值是 DateTime 类型,所以,在处理第一个参数值时,它不知道 Year 属性是否存在。在第二种情况中,我们纠正了这个问题,添加了类型批注,显式指定 dt 值的类型。如果我们使用管道来写前面的代码段,就不需要类型批注,这是使用管道运算符重要的原因:

> Some(DateTime.Now) |> Option.map(fun dt -> dt.Year);;

val it : int option = Some(2008)

现在代码能运行,是因为包含了 DateTime 值的选项值先出现,因此,在 lambda 函数之前被处理;当处理 lambda 函数时,编译器已经知道 dt 的类型肯定是 DateTime,这样,它就可以找到 year 属性,而不会有问题。

到目前为止,我们已经看到了 C# 和 F# 有关类型推断的相似之处,但 F# 走得更远;现在,我们就看一下 F# 编译器对写高阶函数的帮助。

时间: 2024-11-10 08:21:24

6.6.1 F# 中函数调用的类型推断的相关文章

简答的理解C语言中的各种类型函数

1.变参函数 变长参数的函数即参数个数可变.参数类型不定 的函数.最常见的例子是printf函数.scanf函数和高级语言的Format函数.在C/C++中,为了通知编译器函数的参数个数和类型可变(即是不定的.未知的),就必须以三个点结束该函数的声明. 1 // printf函数的声明 2 int printf(const char * _Format, ...); //const char * _Format是格式控制,控制有多少个%d...,确定输出的个数与类型 3 4 //scanf函数声

12.5.3 在 F# 中实现计算生成器

在计算表达式块前面的标识符,是类的实例,把所需的操作实现成为实例成员.许多操作都已经有了,我们根本不必要提供所有的,最基本的操作用 Bind 和 Return 成员实现.当 F# 编译器看到计算表达式,比如清单 12.18 时,会把它转换为使用这些成员的F# 代码.F# 示例转换成这样: value.Bind(ReadInt(), fun n –> value.Bind(ReadInt(), fun m–> let add = n + m let sub = n – m value.Retur

关于void*类型的用法(相当于OC中的id类型)

关于void*类型的用法(相当于OC中的id类型) 1.C++语言在对于void* 类型的使用很特别,因为void* 可以间接引用任何其他数据类型的指针,比如int*.float*甚至抽象数据类型的指针,而且可以从void* 强制转换为任何其他数据类型的指针,所以使用起来有时候会比较危险.如果开始将一个void*的指针间接引用一个float*的指针,然后将这个void*指针强制转化为一个int*类型的指针,编译器不会给出错误甚至警告,但是输出的数据却匪夷所思,如果再强制转换会float*则不会出

ASP中函数调用对参数的影响

在ASP编程中,经常需要自己编写一些函数(或过程)来实现某些特定的功能,这时往往需要向函数(或过程)传递相应的参数 在函数(或过程)中进行数据处理,即有可能需要保留或改变参数的值,下面有相关范例 用下面的函数(TestAddress)就可以使一个函数多个返回值成为可能(一个函数返回值,多个参数改变后的值) 范例: <%@LANGUAGE="VBSCRIPT"%> <% Option Explicit '=================================

ES6中的Symbol类型

前面的话 ES5中包含5种原始类型:字符串.数字.布尔值.null和undefined.ES6引入了第6种原始类型--Symbol ES5的对象属性名都是字符串,很容易造成属性名冲突.比如,使用了一个他人提供的对象,想为这个对象添加新的方法,新方法的名字就有可能与现有方法产生冲突.如果有一种机制,保证每个属性的名字都是独一无二的,这样就从根本上防止了属性名冲突.这就是ES6引入Symbol的原因,本文将详细介绍ES6中的Symbol类型 创建 Symbol 值通过Symbol函数生成.这就是说,

(12)Powershell中变量的类型

Window Powershell中变量的类型与Java,C#等高级语言中变量的类型不一样,可以不用显示指定Powershell中变量的类型,即Powershell中的变量具有更大的灵活性.Powershell中的变量采用 .Net Framework类型. 默认情况下,当变量只有一个值时,变量的数据类型由赋予变量的值决定.例如,下面的语句创建一个整数 (System.Int32) 类型的变量: PS C:\> $a=3 如果需要确定变量的 .NET Framework 类型,可以使用 GetT

9.4.2.2 F# 中的向上转换和向下转换(UPCASTS AND DOWNCASTS)

9.4.2.2 F# 中的向上转换和向下转换(UPCASTSAND DOWNCASTS) 如果类型之间的转换不会失败,就称为向上转换(upcast).我们已经看到,把类型转换成由该类型实现的接口,就是这种情况:另一个示例是把派生类转换成它的基类,在这种情况下,编译器也可以保证操作是正确的,不会失败. 如果有一个基本类型的值,希望将它转换为继承类,操作可能会失败,因为基类的值可能是目标类的值,也可能不是.在这种情况下,我们必须使用第二种类型转换,称为向下转换(downcast).让我们用一个示例来

ARM系统中函数调用过程中的参数传递-转

在 嵌入式软件编程中,经常会用到函数调用,之前在学习如何在C语言中嵌入汇编时有了解到C语言之前的参数调用是使用寄存器R0传递第一个参数,R1传递到第 二个..一直到R3传递第四个参数.但是实际上有时可能传递的参数非常多,超过8个,或是参数中有浮点数之类,参数也会超过4个寄存器,对于超出的部份并 不使用R4,而是使用堆栈的方式,但具体是如何的方式很多网站就没了下文了. 对于ARM体系来说,不同语言撰写的函数之间相互调用(mix calls)遵循的是 ATPCS(ARM-Thumb Procedur

命名空间“System”中不存在类型或命名空间名称“Linq”。是否缺少程序集引用?

完整错误信息 错误 1 命名空间"System"中不存在类型或命名空间名称"Linq".是否缺少程序集引用? F:\CsProjects\CSharp实现SPY++\CSharp实现SPY++\Form1.cs 6 14 CSharp实现SPY++ 错误原因 开始的时候创建项目选择的Framework版本是4.0,但后来为了项目的平台适应性,将Framework的版本改为了2.0,重新编译的时候就产生了这个问题. 解决方法 双击错误信息,会打开引用了System.L