2011-02-06 21 views
2

私はスカラズを使って、スケアを感じるような感覚を少し持たせました。 どのようにスカラで動作するかを理解するために、私はさまざまな代数構造を実装し始め、Scalazの人々によって言及された振る舞いを見つけました。ここでスカラ:型推論とサブタイプ/高級型

はファンクタを実装して、私のサンプルコードです:

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 fooのファンクタインスタンスを書きました。問題は、Scalaは、明示的な型注釈や

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

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

Scalaは、これらの回避策なし[一部]のFunctor [バー]とのFunctorのようなタイプを推測するラッパー・メソッドなしで暗黙のパラメータを推測することができないということです。

なぜですか?誰もこの動作を定義する言語仕様のセクションを教えてください。

よろしく、 次の2つのタスクを実行するために、コンパイラを求めている

+2

類似:http://stackoverflow.com/questions/3816251/implicit-parameter-resolution-problem-for-higher-kinded-types – retronym

+0

ありがとうございます:) – raichoo

答えて

6

raichoo:(§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]は適合しません。