2011-02-06 46 views
2

我一直在玩Scalaz,以將haskell的感覺變成scala。到 瞭解事情如何在scala中工作我自己開始實現各種代數結構,並且遇到了斯卡拉人員提到的行爲。Scala:類型推理和子類型/高級類型

這裏是我的示例代碼它實現了一個函子:

trait Functor[M[_]] { 
    def fmap[A, B](a: M[A], b: A => B): M[B] 
} 

sealed abstract class Foo[+A] 
case class Bar[A]() extends Foo[A] 
case class Baz[A]() extends Foo[A] 

object Functor { 

    implicit val optionFunctor: Functor[Option] = new Functor[Option]{ 
    def fmap[A, B](a: Option[A], b: A => B): Option[B] = a match { 
     case Some(x) => Some(b(x)) 
     case None => None 
    } 
    } 

    implicit val fooFunctor: Functor[Foo] = new Functor[Foo] { 
    def fmap[A, B](a: Foo[A], b: A => B): Foo[B] = a match { 
     case Bar() => Bar() 
     case Baz() => Baz() 
    } 
    } 
} 

object Main { 
    import Functor._ 

    def some[A](a: A): Option[A] = Some(a) 
    def none[A]: Option[A] = None 

    def fmap[M[_], A, B](a: M[A])(b: A => B)(implicit f: Functor[M]): M[B] = 
     f.fmap(a, b) 

    def main(args: Array[String]): Unit = { 
    println(fmap (some(1))(_ + 1)) 
    println(fmap (none)((_: Int) + 1)) 
    println(fmap (Bar(): Foo[Int])((_: Int) + 1))              
    } 
} 

我寫了一個仿函數實例選項和假sumtype富。的問題是,階不能沒有一個明確的類型註釋或包裝方法

def some[A](a: A): Option[A] = Some(a) 

println(fmap (Bar(): Foo[Int])((_: Int) + 1)) 

Scala的推斷類型,如函子[巴]和函子[部份]沒有這些變通方法推斷隱含的參數。

這是爲什麼?任何人都可以請將我指向定義此行爲的語言規範中的部分?

問候, raichoo

+2

類似:http://stackoverflow.com/questions/3816251/implicit-parameter-resolution-problem-for-higher-kinded-types – retronym 2011-02-06 20:47:53

回答

6

你問編譯器執行兩個任務:局部類型推理的類型參數(§6.26.4)來fmap,以及隱含參數隱式搜索(§7.2) f。參考文獻是Scala Reference

事情去大致順序如下:

fmap[M = ?, A = ?, B = ?](Some(1))(x => x) 

// type the arguments of the first parameter section. This is done 
// without an expected type, as `M` and `A` are undetermined. 
fmap[M = ?, A = ?, B = ?](Some(1): Some[Int])(x => x)(?) 

// local type inference determines `M` and `A` 
fmap[Some, Int, B = ?](Some(1): Some[Int])(x => x)(?) 

// move to the second parameter section, type the argument with the expected type 
// `Function1[Int, ?]`. The argument has the type `Function1[Int, Int]` 
fmap[Some, Int, ?](Some(1): Some[Int])((x: Int) => x)             

// local type inference determines that B = Int 
fmap[Some, Int, Int](Some(1): Some[Int])((x: Int) => x) 

// search local identifiers, and failing that the implicit scope of type `Functor[Some]]`, for an implicit 
// value that conforms to `Functor[Some]` 
fmap[Some, Int, Int](Some(1): Some[Int])((x: Int) => x)(implicitly[Functor[Some]]) 

Functor[Some]隱式搜索失敗; Functor[Option]不符合。