在C#中,大多数每个表达式都有一个类型,但有一些例外:
也许是我不知道的其他人。这些使得类型推断变得不可能,例如这是非法的:
var a = null;
F#是一种语言,其中一切都是表达式:F#中的任何表达式都没有类型吗? (我只是在交互式中输入了let a = null
,它返回a
属于通用类型a'
,但我不确定这是否意味着F#null
是通用的类型或无类型。)
答案 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