2013-05-29 122 views
4

请考虑下面的代码片段(它表明我的实际问题的简化版本):斯卡拉:高kinded类型作为类型参数

trait Id[Type[_]] { 
    def id[S]: S => Type[S] 
} 

trait IdTransformer[Type[_]] { 
    type Result[_] // depends of Type 
    def idTransform[P]: P => Result[P] 
    def composeWith[Other[_]](other: Id[Other]) = new Id[Result[Other]] { def id[S] = x => idTransform(other.id(x)) } 
} 

// instance example 
class OptionIdTransformer extends IdTransformer[Option] { 
    type Result = Option[_] 
    def idTransform[S] = x => Some(x) 
} 

在那里,我有标识特质定义包装值的函数转换为类型,并且IdTransformer特性定义了一种将新逻辑添加到id操作的方法。我想用他们的方式像

Transformer1.composeWith(Transformer2.composeWith(...(idInstance))) 

但是,当我编译代码时,我得到错误信息

type Other takes type parameters 

IdTransformer.this.Result[<error>] takes no type parameters, expected: one 
的方法composeWith

,虽然结果[其他]应该是更高级的类型,并且应该采用单个类型参数。

请说明错误的原因以及是否有解决方法。

回答

1

你正试图用两个其他hihgher-kinded类型组成一个更高kinded类型。这个叫做type lambda的技巧需要什么。

trait IdTransformer[Type[_]] { 
    type Result[_] // depends of Type 
    def idTransform[P]: P => Result[P] 
    def composeWith[Other[_]](other: Id[Other]) = new Id[({type λ[α] = Result[Other[α]]})#λ] { def id[S] = x => idTransform(other.id(x)) } 
}