scala - Scala 中带有两个参数的类型构造函数的仿函数实例

标签 scala typeclass scalaz type-constructor kind-projector

我有一个类Foo有两个参数,我正在尝试为第一个参数固定的 Foo 编写一个 Functor 实例,如下所示:

object Scratchpad {

  trait Functor[F[_]] {
    def fmap[A, B](f: A => B): F[A] => F[B]
  }

  case class Foo[X, Y](value: Y)

  implicit def fooInstances[X]: Functor[Foo[X, _]] =
    new Functor[Foo[X, _]] {
      def fmap[A, B](f: A => B): Foo[X, A] => Foo[X, B] =
        foo => Foo[X, B](f(foo.value))
    }
}

但是上面的代码编译失败,产生如下错误:
Error:(9, 41) Scratchpad.Foo[X, _] takes no type parameters, expected: one
  implicit def fooInstances[X]: Functor[Foo[X, _]] =

我知道 Scalaz 用他们的 \/ 做了类似的事情类型,但检查他们的源代码发现一个奇怪的 ? ,它不会为我编译:
implicit def DisjunctionInstances1[L]: Traverse[L \/ ?] with Monad[L \/ ?] with BindRec[L \/ ?] with Cozip[L \/ ?] with Plus[L \/ ?] with Optional[L \/ ?] with MonadError[L \/ ?, L] =

Scalaz 怎么样?工作,以及如何为 Foo 编写 Functor 实例?

最佳答案

but inspection of their source code reveals an odd ?, which doesn't compile for me


?来自 kind-projector 项目,这是一个 Scala 编译器插件,您需要添加到您的 build.sbt :
resolvers += Resolver.sonatypeRepo("releases")

addCompilerPlugin("org.spire-math" %% "kind-projector" % "0.9.4")

这为您美化了类型 lambda 的创建:
implicit def fooInstances[X]: Functor[Foo[X, ?]] =
  new Functor[Foo[X, ?]] {
    def fmap[A, B](f: A => B): Foo[X, A] => Foo[X, B] =
      foo => Foo[X, B](f(foo.value))
}

请记住,我们还可以使用具有类型别名的部分类型应用程序:
implicit def fooInstances[X] = {
  type PartiallyAppliedFoo[A] = Foo[X, A]
  new Functor[PartiallyAppliedFoo] {
    override def fmap[A, B](f: (A) => B): (PartiallyAppliedFoo[A]) => PartiallyAppliedFoo[B] = foo => Foo[X, B](f(foo.value))
  }
}

编辑 (05/04/2020)

注意 kind 项目的语法从 ? 改变了。至 *对于部分应用类型,因此上面的示例应该是:

sbt:
resolvers += Resolver.sonatypeRepo("releases")

addCompilerPlugin("org.spire-math" %% "kind-projector" % "0.11.0")

代码:
implicit def fooInstances[X]: Functor[Foo[X, *]] =
  new Functor[Foo[X, *]] {
    def fmap[A, B](f: A => B): Foo[X, A] => Foo[X, B] =
      foo => Foo[X, B](f(foo.value))
}

关于scala - Scala 中带有两个参数的类型构造函数的仿函数实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45271911/

相关文章:

scala - 如何在 ZIO 测试中忽略套件或测试?

java - 使用无限通配符等将 Scala 类型的集合转换为 Java Collection<?>

scala - Scala 中是否可以同时具有隐式 Ordering[Option[T] 和 Ordered[Option[T]] ?

haskell - 定义部分应用的类型类

haskell - 在 Haskell 中分解多个类型类的简洁方法?

Scala双重定义(2个方法具有相同的类型删除)

java - 如何在 Java/Scala 中中断提交给 newSingleThreadExecutor 的线程?

scala - 使用 Unapply 提取相同的类型类

scala - 如何为泛型类型编写 scalaz.IsEmpty 参数

scala - 组合 2 个列表的元素