Scala 中带有两个参数的类型构造函数的函子实例 [英] Functor Instance for Type Constructor with Two Parameters in Scala

查看:67
本文介绍了Scala 中带有两个参数的类型构造函数的函子实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a class Foo with two parameters, and I am trying to write a Functor instance for Foo with the first parameter fixed, as follows:

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))
    }
}

但是上面的代码编译失败,产生如下错误:

But the above code fails to compile, generating the following error:

Error:(9, 41) Scratchpad.Foo[X, _] takes no type parameters, expected: one
  implicit def fooInstances[X]: Functor[Foo[X, _]] =

我知道 Scalaz 用他们的 \/ 类型做了这样的事情,但是检查他们的源代码发现一个奇怪的 ?,它不适合我编译:

I know Scalaz does something like this with their \/ type, but inspection of their source code reveals an odd ?, which doesn't compile for me:

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 实例?

How does the Scalaz ? work, and how can I write a Functor instance for Foo?

推荐答案

您希望部分应用类型级构造函数.不幸的是,我们不能直接做到这一点.但是,我们仍然可以使用一个名为 Structural Types 的小功能间接地做到这一点.为了将 Foo 从双参数类型构造函数转变为单参数类型构造函数,我们将在匿名结构类型中定义类型同义词.

You're looking to partially apply a type-level constructor. Unfortunately, we can't directly do that. However, we can still do so indirectly using a little feature called Structural Types. In order to turn Foo from a two-argument type constructor into a one-argument type constructor, we'll define a type synonym inside of an anonymous, structural type.

implicit def fooInstances[X]: Functor[({ type T[A] = Foo[X, A] })#T] =
  new Functor[({ type T[A] = Foo[X, A] })#T] {
    // ...
  }

类型上下文中的大括号 {} 定义了一个匿名类型,我们正在利用该类型本质上在类型级别创建一个 lambda 函数.我们定义一个匿名类型,其中包含一个别名,然后立即评估该别名.

The braces {} in a type context define an anonymous type that we're exploiting to essentially create a lambda function at the type level. We define an anonymous type with an alias inside of it, then immediately evaluate that alias.

这篇关于Scala 中带有两个参数的类型构造函数的函子实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆