【问题标题】:In Scala, is there a shorthand for reducing a generic type's arity?在 Scala 中,是否有减少泛型类型数量的简写?
【发布时间】:2011-10-04 05:00:50
【问题描述】:

我想调用 Scalaz 的 pure 方法将值放入 State monad。以下作品:

type IntState[A] = State[Int, A]
val a = "a".pure[IntState]
a(1)
    (Int, java.lang.String) = (1,a)

我还可以消除类型别名(感谢 Scalaz 的 Pure.scala):

val a = "a".pure[({type T[A]=State[Int,A]})#T]
a(1)
    (Int, java.lang.String) = (1,a)

但这非常笨拙。有没有更短的方法来合成这样的类型?就像函数文字的占位符语法一样,有没有类似的东西:

"a".pure[State[Int, *]]

【问题讨论】:

标签: generics scala scalaz


【解决方案1】:

对于 Scala 中简洁的部分类型应用程序(arity-2),您可以将类型表示法中缀如下。

type ![F[_, _], X] = TF { type ![Y] = F[X,  Y] }

"a".pure[(State!Int)# !]

请注意,我们可以为两个 arity 类型构造函数(或类型别名)添加符号。

【讨论】:

  • 我将第二个! 重命名为?,这样我就可以写(State!Int)#?
  • 类型成员最好使用非运算符名称,因此您可以跳过类型投影后的空格,即:trait ![F[_, _], A] { type X[B] = F[A, B] }; foo[(State!Int)#X]。不要认为它可以变得比这更紧凑。
【解决方案2】:

不确定这是否更好,但这是@kmizu 前几天在推特上发布的一种方法:

scala> trait TF {
     |   type Apply[A]
     | }
defined trait TF

scala> type Curried2[F[_, _]] = TF {
     |   type Apply[X] = TF {
     |     type Apply[Y] = F[X, Y]
     |   }
     | }
defined type alias Curried2

scala> "a".pure[Curried2[State]#Apply[Int]#Apply]
res7: scalaz.State[Int,java.lang.String] = scalaz.States$$anon$1@1dc1d18

您可以通过使用符号类型别名使它看起来更漂亮。

scala> type ![F[_, _]] = TF {
     |   type ![X] = TF {
     |     type ![Y] = F[X, Y]
     |   }
     | }
defined type alias $bang

scala> "a".pure[![State]# ![Int]# !]
res9: scalaz.State[Int,java.lang.String] = scalaz.States$$anon$1@1740235

【讨论】:

  • 当你想绑定第一个类型参数时会发生什么?我猜你需要另一个版本的 Curried2?
  • @IttayD:这不会被称为柯里化,在这种情况下你最好使用类型 lambda 语法。 (Tony Morris 在一些邮件列表中也注意到了类型 lambda 语法相对于 Haskell 的柯里化类型构造函数语法的这个小优势。)我在这个答案中建议的语法是用于模拟 Haskell 样式的部分类型应用程序。 ![State]# ! 相当于 Haskell 中的 State![State]# ![Int]# ! 相当于 State Int 等。
  • @JesperNordenberg,我认为这不是投反对票的好理由。
【解决方案3】:

最流行的减少 arity 的方法是 kind-projector (https://github.com/non/kind-projector) 插件,它也用于 cat 库中。通过启用此插件,您的示例可以转换为:

val a = "a".pure[State[Int, ?]]

注意:默认情况下,此语法将在 Dotty 中启用。

【讨论】:

    猜你喜欢
    • 2021-08-19
    • 2020-07-17
    • 2021-07-16
    • 2015-07-09
    • 2020-03-27
    • 2018-01-01
    • 2020-09-10
    • 2017-08-21
    相关资源
    最近更新 更多