我想调用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, *]]
答案 0 :(得分:6)
不确定这是否更合适,但这是@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
答案 1 :(得分:6)
对于Scala中的简明部分类型应用程序(arity-2),您可以将类型表示法中缀为以下内容。
type ![F[_, _], X] = TF { type ![Y] = F[X, Y] }
"a".pure[(State!Int)# !]
请注意,我们可以为两个arity类型构造函数(或类型别名)添加表示法。
答案 2 :(得分:1)
最常用的减少arity的方法是kind-projector(https://github.com/non/kind-projector)插件,它也用于猫库。通过启用此插件,您的示例可以转换为:
val a = "a".pure[State[Int, ?]]
注意:默认情况下,此语法将在Dotty中启用。