Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
803 views
in Technique[技术] by (71.8m points)

scala - Context bounds shortcut with higher kinded-types

Is it possible to use the context bounds syntax shortcut with higher kinded-types?

trait One { def test[W   : ClassManifest]: Unit } // first-order ok
trait Two { def test[W[_]: ClassManifest]: Unit } // not possible??
trait Six { def test[W[_]](implicit m: ClassManifest[W[_]]): Unit } // hmm...
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Yes, it is, but your context bound type must have a higher kinded type parameter (which ClassManifest doesn't).

scala> trait HKTypeClass[CC[_]]
defined trait HKTypeClass

scala> implicit def listHKTC = new HKTypeClass[List] {}
listHKTC: java.lang.Object with HKTypeClass[List]

scala> def frob[CC[_] : HKTypeClass] = implicitly[HKTypeClass[CC]]
frob: [CC[_]](implicit evidence$1: HKTypeClass[CC])HKTypeClass[CC]

scala> frob[List]
res0: HKTypeClass[List] = $anon$1@13e02ed

Update

It's possible to use a type alias to allow a higher-kinded type parameter to be bounded by a first-order context bound type. We use the type alias as a type-level function to make a higher-kinded type out of the first-order type. For ClassManifest it could go like this,

scala> type HKClassManifest[CC[_]] = ClassManifest[CC[_]]
defined type alias HKClassManifest

scala> def frob[CC[_] : HKClassManifest] = implicitly[HKClassManifest[CC]]         
test: [CC[_]](implicit evidence$1: HKClassManifest[CC])HKClassManifest[CC]

scala> frob[List]                                                       
res1: HKClassManifest[List] = scala.collection.immutable.List[Any]

Note that on the right hand side of the type alias CC[_] is a first-order type ... the underscore here is the wildcard. Consequently it can be used as the type argument for ClassManifest.

Update

For completeness I should note that the type alias can be inlined using a type lambda,

scala> def frob[CC[_] : ({ type λ[X[_]] = ClassManifest[X[_]] })#λ] = implicitly[ClassManifest[CC[_]]]     
frob: [CC[_]](implicit evidence$1: scala.reflect.ClassManifest[CC[_]])scala.reflect.ClassManifest[CC[_]]

scala> frob[List]
res0: scala.reflect.ClassManifest[List[_]] = scala.collection.immutable.List[Any]

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...