11

我想调用 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, *]]
4

3 回答 3

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
于 2011-10-04T05:52:16.170 回答
6

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

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

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

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

于 2011-10-04T14:29:45.660 回答
1

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

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

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

于 2017-09-20T19:34:25.473 回答