使用类型成员减少Scala中的类型冗长度是否可行?
所以,这可能听起来像是一个关于语言设计的一般问题,但我认为这里有一些具体的东西.具体来说,我感兴趣的是什么技术挑战阻止通常使用的kludgy代码.
我们都知道,“Scala的类型推论不如Haskell的那样好”,而且有很多原因,它不能那么好,而且仍然是Scala所做的一切.但是,在Scala编程足够长的时间之后,也是显而易见的,那么差的类型推断并不是那么糟糕,所以指定一些常见类型所需的冗长度也是如此.所以,例如,在多态尾函数中, def tail[A](ls: List[A]) = ls match { case Nil => sys.error("Empty list") case x :: xs => xs } 为了使该方法有用,需要明确命名一个类型参数;没有办法. tail(ls:List [Any])将不起作用,因为Scala无法确定输出类型的结果类型是一样的,即使对于人来说这是“显而易见的”. 所以,受到这个困难的启发,并且知道Scala有时可以比类型成员更聪明,而不是类型参数,我写了一个使用类型成员的List的版本: sealed trait TMList { self => type Of def :::(x: Of) = new TMCons { type Of = self.Of val head = x val tail = (self: TMList { type Of = self.Of }) } } abstract class TMNil extends TMList def ATMNil[A] = new TMNil { type Of = A } abstract class TMCons extends TMList { self => val head: Of val tail: TMList { type Of = self.Of } } 好的,定义看起来很可怕,但它至少是直截了当的,它允许我们编写我们的尾部方法如下: def tail4(ls: TMList) = ls match { case _: TMNil => sys.error("Empty list") case c: TMCons with ls.type => c.tail } 美丽的是,这是有效的,所以我们可以写(按照你的期望定义) val ls = 1 ::: 2 ::: ATMNil val a = tail4(ls) println(head4(a) * head4(a)) 而Scala知道输出类型成员仍然是Int.我们不得不使用ls.type写一些有趣的TMCons,而Scala则抱怨说这个比赛并不详尽,但是这个代码可能只是被Scala插入我们的,因为当你在任何情况下必须是ls.type,当然匹配是穷尽的. 所以我的问题是:有什么东西?为什么我们不这样做所有的多态类型,只是修改语言,使语法看起来不那么糟糕?我们遇到什么技术问题? 显然有一个问题是类不能在其类型成员中是协变的;但我对此并不感兴趣我认为这是一个单独的问题.假设我们不关心方差.还有什么问题吗? 我怀疑这可能会引入类型推理的新问题(就像我必须如何定义ATMNil的例子一样),但是我不明白Scala的类型推断能够很好地知道那些是什么. 编辑回应0__:我想你可能已经找到了.具有类型参数的版本可以工作, def move2[A](a: TMList { type Of = A },b: TMList { type Of = A }) = b match { case c: TMCons with b.type => c.head ::: a case _ => a } 但有趣的是,没有明确的返回类型,一个咖喱的依赖类型的版本不会: def move3(a: TMList)(b: TMList { type Of = a.Of }) = b match { case c: TMCons with b.type => c.head ::: a case _ => a } Scala推测返回类型为TMList;这是两种类型的上限,TMList {type Of = a.Of}和a.type.当然,TMList {type Of = a.Of}也将是一个上限(和我想要的一个),这就是为什么添加一个显式返回类型的工作原理),而且我认为一个更具体的上界.我不知道为什么Scala不会推断出更具体的上限. 解决方法
尝试用TMList重写以下内容:
def move[A](a: List[A],b: List[A]): List[A] = b match { case head :: _ => head :: a case _ => a } move(List(1,2,3),List(4,5,6)) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Bootstrap在jsp及html中的使用
- linux – 安装libmemcached时出错
- Angular AOT编译器 – TypeError:this.compiler
- Unix-Linux操作系统中如何在sqlplus-rman中使用方
- Angular 2 – 具有依赖性的angular-cli管道测试
- AngularJS:禁用或删除生成的HTML中的ng-scope和
- @ angular / core / testing没有导出成员’MockA
- angularjs申明$scope.xx = function()是有顺序的
- angularjs – 量角器控制台日志
- Angular 6 Server Side Errror:找不到模块:错误