首页 文章

Scala:类型推断和子类型/更高级的类型

提问于
浏览
2

我一直在和Scalaz一起玩,以获得scala的一点点haskell感觉 . 为了理解scala中的工作原理,我开始自己实现各种代数结构,并且遇到了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))                                                    
  }
}

我为Option写了一个仿函数实例,伪造了一个类型Foo . 问题是如果没有显式类型注释或包装器方法,scala无法推断隐式参数

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

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

Scala推断类型如Functor [Bar]和Functor [Some]没有那些变通方法 .

这是为什么?有谁能请指出我在语言规范中定义这种行为的部分?

问候,raichoo

1 回答

  • 6

    您要求编译器执行两个任务: fmap 类型参数的本地类型推断(第6.26.4节),以及隐式参数(第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] 不符合 .

相关问题