【问题标题】:Type constructor parameter inference类型构造函数参数推断
【发布时间】:2020-10-17 23:44:24
【问题描述】:

我正在浏览“Scala with cats”。在 3.5.2(第 58 页,底部)中有一个示例:

def doMath[F[_]](start: F[Int])(implicit functor: Functor[F]): F[Int] =
    start.map(n => n + 1 * 2)

而且用法非常简单:

import cats.instances.option._ // for Functor
import cats.instances.list._
// for Functor
doMath(Option(20))
// res3: Option[Int] = Some(22)
doMath(List(1, 2, 3))
// res4: List[Int] = List(3, 4, 5)

我应该如何理解方法签名(F[_])中的类型构造函数?前几页说过,应该提供类型参数来创建类型。这里整个(F[_])是一个类型参数,看起来_是一个通配符,所以编译器可以推断F的类型参数。

【问题讨论】:

    标签: scala types scala-cats category-theory type-constructor


    【解决方案1】:

    类型构造函数F[_] 必须是Functor 类型类的成员。这个约束被隐式参数列表放在F

    (implicit functor: Functor[F])
    

    整个签名

    def doMath[F[_]](start: F[Int])(implicit functor: Functor[F]): F[Int]
    

    可能解释如下

    给定任何类型的构造函数 FFunctor 的成员 typeclass,则doMath 可以将F[Int] 类型的有效值转换为 F[Int] 类型的另一个有效值。

    我使用短语有效值来强调它不是原始类型的值,例如Int,而是在将类型构造函数F应用于类型参数后构造的类型值Int,即F[Int]

    此外,我在sense of中使用了短语成员

    形成,或参与,或有关系

    请注意,在此上下文中使用下划线 _ 与推理无关。 F[X]F[_] 类型的构造函数表示法正是 same 的意思。类型参数X 没有在方法签名的其余部分中使用,因此按照惯例,我们使用下划线语法F[_]。另一种约定是在F[x] 中使用小写x,而不是F[X],以强调不使用x

    确实F[_] 本身就是一个类型参数,当类型构造函数Functor 应用于它时,我们得到正确 类型Functor[F],即使FFunctor是类型构造函数,例如

    scala> :kind -v List
    List's kind is F[+A]
    * -(+)-> *
    This is a type constructor: a 1st-order-kinded type.
    
    scala> :kind -v cats.Functor
    cats.Functor's kind is X[F[A]]
    (* -> *) -> *
    This is a type constructor that takes type constructor(s): a higher-kinded type.
    
    scala> :kind -v cats.Functor[List]
    cats.Functor[List]'s kind is A
    *
    This is a proper type.
    

    【讨论】:

    • 次要注意,最好说类型构造函数F 应该遵守函子定律。或者它存在类型构造函数F 的函子实例。而不是说F 是仿函数的成员。请记住,子类型和类型类之间的主要概念区别在于,在前者中 A is a B,而在最后一个 A 有一个(实例)B
    • @LuisMiguelMejíaSuárez 我在 danielwestheide.com/blog/… 的意义上使用了 member 这个词,我猜它来自 Haskell,但是我确实看到这会根据 OO 术语造成混淆.
    • 嗯,我第一次看到要在类型类上下文中使用的表达式成员。也许,正如你所说,它来自 Haskell?有趣的文章,谢谢分享。
    猜你喜欢
    • 2019-09-23
    • 1970-01-01
    • 2022-01-26
    • 2019-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-30
    相关资源
    最近更新 更多