我實現了一個TList
,可以收集任何類型的H
。但我發現它不能包含更高訂單類型H[_]
。所以我拷貝了整個東西,並把[_]
添加到尊重的地方。如何抽象類型類型?
雖然出現在我的腦海裏。如果我需要存儲H[_[_]]
,H[_[_,_]]
甚至H[_[_[_]]]
,該怎麼辦?我應該隨時複製代碼嗎?有沒有什麼方法可以抽象出類型的好意?
我實現了一個TList
,可以收集任何類型的H
。但我發現它不能包含更高訂單類型H[_]
。所以我拷貝了整個東西,並把[_]
添加到尊重的地方。如何抽象類型類型?
雖然出現在我的腦海裏。如果我需要存儲H[_[_]]
,H[_[_,_]]
甚至H[_[_[_]]]
,該怎麼辦?我應該隨時複製代碼嗎?有沒有什麼方法可以抽象出類型的好意?
在Scala中沒有rank-2多態性。它意味着方法(除此之外甚至不是多態的函數)除了具有通用量詞的參數之外不能(除了方法級別的所有通用量化)。因此,我們可以有一個像
def f[A, B[_], C[_[_]]](x: A, y: B[A], z: C[B]) = ???
方法,但不喜歡(僞)
def f(x: [A] A, y: [A1, B[_]] B[A1], z: [B1[_], C[_[_]]] C[B1]) = ???
而且這意味着我們無法替代型構造到特定類型的預期的地方(實際上是一個類型構造函數B[_]
可以認爲是[A] B[A]
,C[_[_]]]
,作爲[B[_]] C[B]
或[[A] B[A]] C[B]
)。
但是爲了讓類型和類型構造函數看起來更加一致,你可以使用特徵類型來包裝一個類型構造函數。例如,你可以看看下面的編碼(這是肯定羅嗦,你必須包裝,拆開包裝類型所有的時間):
trait Type
trait ConcreteType extends Type {
type T
}
trait TypeConstructor[U] extends Type {
type l[X <: U] <: ConcreteType
}
type Type0 = ConcreteType
type Type1 = TypeConstructor[Type0]
type Type2 = TypeConstructor[Type1]
type Type3 = TypeConstructor[Type2]
// type A = Int
type A = Type0 {type T = Int}
// type B[X] = List[X]
type B = Type1 {
type l[X <: Type0] = Type0 {type T = List[X#T]}
}
trait Functor[F[_]]
// type C[F[_]] = Functor[F]
type C = Type2 {
type l[F <: Type1] = Type0 {
type T = Functor[
({
type ll[X] = (F#l[Type0 {type T = X}])#T
})#ll
]
}
}
trait Generic[FF[_[_]]] // like shapeless.Generic1, shapeless.IsHCons1, shapeless.IsCCons1
// Generic1[F[_], FR[_[_]]], IsHCons1[L[_], FH[_[_]], FT[_[_]]], IsCCons1[L[_], FH[_[_]], FT[_[_]]]
// Generic1[F, Functor], IsHCons1[L, Monad, Monad], IsCCons1[L, Applicative, Applicative]
// type D[FF[_[_]]] = Generic[FF]
type D = Type3 {
type l[FF <: Type2] = Type0 {
type T = Generic[
({
type ll[F[_]] = (
FF#l[Type1 {
type l[X <: Type0] = Type0 {type T = F[X#T]}
}]
)#T
})#ll
]
}
}
import shapeless.{::, HNil}
type lst = A :: B :: C :: D :: HNil
一些鏈接:
https://wiki.haskell.org/Rank-N_types
https://en.wikibooks.org/wiki/Haskell/Polymorphism#Higher_rank_types
https://apocalisp.wordpress.com/2010/07/02/higher-rank-polymorphism-in-scala/
我習慣於這樣的結構:'[X,U [_ <:X],H [Y <:X] <:U [Y ]]'。它看起來非常難看,特別是當它連續發生兩次時 – ayvango
認爲您正在尋找:https://underscore.io/blog/posts/2016/12/05/type-lambdas.html。你也可以展示你到目前爲止? – pedromss
沒什麼特別的,就像正常的無形練習。儘管如此,類型lambdas仍然會鍵入類型。它允許'*,* - > *'到'* - > *'¸,但它無法編寫容易同時接受'*','* - > *','* - > * - > *' – ayvango
不,但它有助於編寫使用具有特定數量類型的類型的could。我所說的是,而不是重複執行改變你使用它的方式。你的一個片段'TList'和幾個你想達到的例子會有所幫助。 – pedromss