2011-10-04 168 views
11

我想打电话给斯卡拉的pure方法,将价值放入状态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

我不认为斯卡拉有这样的语法糖,因为[michid引用部分类型的应用](http://stackoverflow.com/questions/7045967/what-are-type-projections-useful-for/7046860#7046860 )作为类型投影的实用例子。 –

回答

6

对于Scala中简要局部类型的应用程序(元数-2),可以缀类型表示法如下。

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

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

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

+0

我将第二个'!'重命名为'?',所以我可以写'(State!Int)#?'。 –

+5

对于类型成员,非运算符名称更可取,因此您可以在类型投影后跳过空格,即:[trait![F [_,_],A] {type X [B] = F [A,B ]}; FOO [(国家!智力)#X]'。不要认为它可以比这更紧凑。 –

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] = [email protected] 

可以使它通过使用符号类型别名看起来更好一点。

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] = [email protected] 
+0

当你想绑定第一个类型参数时会发生什么?我想你需要Curried2的另一个版本? – IttayD

+1

@IttayD:这不会被称为currying,在这种情况下最好使用类型lambda语法。 (托尼·莫里斯在一些邮件列表中也注意到了Haskell的curried类型构造函数语法类型的lambda类型语法的一个小优点)。我在这个答案中提出的语法是模拟Haskell类型的部分类型应用程序。 '![State]#!'相当于Haskell中的'State','![State]#![Int]#!'到'State Int'等。 – missingfaktor

+0

@Downvoter:小心解释你的downvote? – missingfaktor

1

减少色度的最流行的方式是类型投影机(https://github.com/non/kind-projector)也用于猫库中的插件。通过启用该插件您的例子可以转化为:

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

注:此语法将在斑点狗默认情况下启用。