高级类型
方法
为达到自由度和表现力的最高级别,Luna允许以多态参数调用方法。
当然,并非总是可能推断结果的类型,所以,这种情况下,将此悬而未决到需要真正类型时。
如果熟悉动态语言的“鸭子类型(Duck Typing)”技术,在Luna中几乎是一样的,除了不是真的可能调用函数(except when it’s not really possible to call the functioni),用户仍然获得一个编译时错误。
考虑如下函数:
def callSucc a: a.succ
是什么类型?
由于没有定义a的类型,分配一个类型参数b。
现在,类型b的succ方法是什么类型?
永远不知道,因为依赖所用a的具体类的实现。
因此,callSucc的类型简单的讲是“b->b.succ”。
可以这样读:需要一个类型是b的参数、返回类b的succ方法返回的任意值。
callSucc 1
则succ方法为Int类型定义
callSucc "hello"
会导致编译错误
类型假定(推断)和类型检查过程
Luna的类型检查器保存一些额外有关类型参数的假定,需要变量的类型代理(subsitute)满足。
这些经常出现在手写的函数和多态值上调用方法。
看一个简单例子,加法在Luna标准库中定义如下:
def + :: a -> a -> a
def + x y = x.+y
该定义允许写这样的表达式:
5 + 7
"foo" + "bar"
却排斥:
"foo" + 5 # 参数类型不同
Just 5 + Just 7 # 没有给Maybe类定义加法
这里真正想表达什么(what is really going on here)?
用户指定的类型表明所有参数和返回值的类型必须相同,加法的使用表明类型a需要定义了加法,且需要一个类型是a的参数、返回值类型也是a。
这些要求可以描述为:
+ :: a -> a -> a
任何这样的a都有“a.+ = a -> a”。
这些都由Luna编译器在后台控制,用户不需要考虑所有假定呈现。
再考虑另一个例子:
def foo x: x.succ + 1
该函数的类型是什么?
可以看到x.succ的结果和Int(1)相加,根据上述加法的定义,得知“x.succ :: Int”且该函数的返回值也是Int。
因此,最后潜在的类型推测是:
foo :: a -> Int
任何这样的a都有“a.succ = Int”。
所有这些假定随着函数复杂、多行生长。
这是Luna咋后台追终的原因,仅在其中有些不满意时暴露。