F#中有没有类型的表达式吗?

时间:2013-12-28 03:35:32

标签: c# f#

在C#中,大多数每个表达式都有一个类型,但有一些例外:

  • null关键字
  • 匿名方法
  • lambda表达式

也许是我不知道的其他人。这些使得类型推断变得不可能,例如这是非法的:

var a = null;

F#是一种语言,其中一切都是表达式:F#中的任何表达式都没有类型吗? (我只是在交互式中输入了let a = null,它返回a属于通用类型a',但我不确定这是否意味着F#null是通用的类型或无类型。)

1 个答案:

答案 0 :(得分:2)

在匿名方法/ lambdas的类型方面,F#与C#没有相同的限制,因为它以不同的方式处理匿名函数,并使用Hindley-Milner type inference为它们推断出一般类型。

将Eric Lippert的例子转换为F#(使用fsi获得即时反馈):

> let f = fun i -> i;;

val f : 'a -> 'a

我们为'a - >'a推断了泛型类型f

然而,在某些情况下,类型推断系统无法在不事先知道类型的情况下处理,这可能提供与C#无类型表达式最接近的类比。例如:

> let f i = i.Value;;

  let f i = i.Value;;
  ----------^^^^^^^

stdin(18,11): error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.

换句话说,如果我们不知道i.Value的类型,则表达式i没有意义,因为编译器无法分辨我们正在使用哪个Value属性并且没有任何方法可以在类型中对其进行抽象。

另一方面,如果我们约束i以便编译器确实知道Value属性是什么,那么一切都很好:

> let f (i : 'a option) = i.Value;;

val f : 'a option -> 'a