2011-10-04 85 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, ?]] 

注:此語法將在斑點狗默認情況下啓用。