Generics 在Scala中,是否有一种简化泛型类型的方法';什么是家庭暴力?

Generics 在Scala中,是否有一种简化泛型类型的方法';什么是家庭暴力?,generics,scala,scalaz,Generics,Scala,Scalaz,我想调用Scalaz的pure方法将值放入状态monad。以下工作: type IntState[A] = State[Int, A] val a = "a".pure[IntState] a(1) (Int, java.lang.String) = (1,a) 我还可以消除类型别名(感谢Scalaz的Pure.scala): 但这是非常笨拙的。有没有较短的方法来合成这样的类型?与函数文字的占位符语法类似,是否存在类似于: "a".pure[State[Int, *]] 不确定这是否

我想调用Scalaz的
pure
方法将值放入状态monad。以下工作:

type IntState[A] = State[Int, A]
val a = "a".pure[IntState]
a(1)
    (Int, java.lang.String) = (1,a)
我还可以消除类型别名(感谢Scalaz的Pure.scala):

但这是非常笨拙的。有没有较短的方法来合成这样的类型?与函数文字的占位符语法类似,是否存在类似于:

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

不确定这是否更好,但前几天@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

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

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

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

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

减少arity最流行的方法是kind projector()插件,该插件也在cats库中使用。通过启用此插件,您的示例可以转换为:

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

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

我认为Scala没有这样的语法优势,因为作为类型投影实用程序的一个示例。当您想要绑定第一个类型参数时会发生什么?我想你需要另一个版本的Curried2?@IttayD:这不会被称为currying,在这种情况下,你最好使用lambda类型语法。(Tony Morris在一些邮件列表中也注意到了类型lambda语法相对于Haskell的curried类型构造函数语法的这一小优势。)我在这个答案中建议的语法用于模拟Haskell风格的部分类型应用程序<代码>![陈述]#相当于Haskell中的状态,
![陈述]#![Int]#
State Int
等等@Jespernodenberg,我不认为这是一个否决投票的好理由。我要重命名第二个
,这样我就可以编写
(State!Int)#?
。类型成员最好使用非运算符名称,这样您就可以跳过类型投影后的空格,即:
trait![F[u,u],A]{type X[B]=F[A,B]};foo[(State!Int)#X]
。别以为它能比那更紧凑。
val a = "a".pure[State[Int, ?]]