Eğer hList L
Scala buna izin vermez çünkü, mümkün değildir sonsuz hList, var anlamına gelir kafasını TypedMap
ve kuyruk L
, sahip olduğu kanıt soruyorsun IsHCons.Aux[L, TypedMap, L]
yazdığınızda keyfi bir şekilde özyinelemeli tür (örneğin, type Foo = Int :: Foo
gibi bir şeyi yazmayı deneyin), "yasadışı döngüsel referans" hatası alırsınız). Muhtemelen istediğin de değil.
Genelde IsHCons
'u Shapeless'da kullanma olasılığınız pek fazla değildir, çünkü türünde istediğiniz yapıyı belirtmek neredeyse her zaman iyidir.
import shapeless._, ops.hlist.IsHCons
def foo[L <: HList](l: L)(implicit ev: IsHCons[L]) = ev.head(l)
Ve: Örneğin, aşağıdaki iki tanım aynı şeyi yapar
def foo[H, T <: HList](l: H :: T) = l.head
Ama ikinci (daha anlaşılır olduğunu açıkça tercih edilir olması için ekstra bir tip sınıfı örneği gerektirmez derleme zamanında bulundu, vb.) ve bu şekilde yapmaya çalıştığınız şeyi yazmak neredeyse her zaman mümkündür.
Ayrıca bir IsHCons
örneği gerektiren belirtti-Bir HNil
üzerinde get
çağrı yapamazsınız olarak (Çünkü değil) derleyici bir HCons
olduğunu ispat edemez çünkü burada tekrarlama, işe yaramaz anlamına geldiği unutulmamalıdır.
Bir hlisteye ihtiyacınız olduğuna emin misiniz? Eğer hlistenin tüm üyelerinin TypedMap
türünü kullanmasını istiyorsanız, Shapeless'in Sized
(türün uzunluğu yakalamasını istiyorsanız) veya hatta sadece düz bir eski List
'u da kullanabilirsiniz. Sonra
trait FindField[L <: HList] {
def find(key: IntegerField, l: L): Option[Int]
}
object FindField {
implicit val findFieldHNil: FindField[HNil] = new FindField[HNil] {
def find(key: IntegerField, l: HNil) = None
}
implicit def findFieldHCons[H <: TypedMap, T <: HList](implicit
fft: FindField[T]
): FindField[H :: T] = new FindField[H :: T] {
def find(key: IntegerField, l: H :: T) = if (l.head.head == key)
Some(l.head.tail.head)
else fft.find(key, l.tail)
}
}
def get[L <: HList](key: IntegerField, l: L)(implicit
ffl: FindField[L]
): Option[Int] = ffl.find(key, l)
Ve:
scala> get(IntegerField("year"), test)
res3: Option[Int] = Some(23)
scala> get(IntegerField("foo"), test)
res4: Option[Int] = None
Bu oldukça yaygın desen içindedir gerçekten, gerçekten burada bir HList
kullanmak istiyorsanız
, ben yeni bir tür sınıf yazma öneririm Shapeless — siz boş bir hlisteki bir operasyonu nasıl yapacağınızı, daha sonra işlemi nasıl yapacağınızı bildiğiniz bir kuyruğa hazır bir kafa ile bir hlistde nasıl indükleyeceğinizi açıklıyorsunuz.
Teşekkürler! Bunun gibi aptalca göründüğünü biliyorum. Amacım, shapeless 'HMap' gibi bir şey inşa etmektir, ancak' 'IntegerField',' StringField' yerine '' Jenerik 'Alan [T]' örneğini kabul eden 'get()' fonksiyonu ile ... Örneğinizde Aradığınız ürün ilk değilse, nasıl tekrarlanırsınız? Eğer bulmaya çalışırsam '' bul (anahtar, l.kutu) '' ı buldum: T, gerekli: shapeless. :: [H, T], '--- bu yüzden isHCons.Aux'unu deniyordum. – kenshin
Ah, iyi yakalama — Yanlış yazdım ve “findFieldHCons” öğesini güncelledim, böylece gerçekten çalışıyor. –
Fantastik! Aptal-aşağı sürümü bile bir çekicilik gibi çalışır. Teşekkür ederim :) – kenshin