SORU
6 AĞUSTOS 2012, PAZARTESİ


HLists dizilerini yazma dolambaçlı bir yoldan başka bir şey daha vardır?

Umarım provokatif bir başlık yakaladı dikkat :-) Rağmen ilk izlenim bu olabilir bırakın, ben gerçekten ilgileniyor bulmak farklar nelerdir, ve daha genel olarak tanımlamak için kurallı kullanım durumları nerede HLists kullanılamaz (ya da daha doğrusu, yok verim herhangi bir yarar düzenli listeler).

(Sipariş için boşa zaman ve emek: farkındayım vardır 22 (sanırım) TupleN Scala, oysa tek ihtiyaçları bir tek HList, ama bu tür bir kavramsal fark ediyorum ilgileniyor.)

Aşağıdaki metinde bir kaç soru işaretledim. Aslında onlara cevap vermek için yeterli olmayabilir, daha fazla beni anlamadığınız şeyleri işaret etmek içindir, ve belirli bir yönde tartışma rehberi.

Motivasyon

Son zamanlarda insanlar HLists (örneğin, Shapeless tarafından sağlanan gibi), this question için bir cevap dahil olmak üzere kullanmak için önerilen bu YÜZDEN birkaç cevap gördüm (Not:ne yazık ki çoktan silinmiş cevap). Bu soruya yol açtı this discussion, sebebiyet verdi.

İntro

Hlists elemanları ve hassas türleri sayısı statik olarak bildiğiniz yararlı olur gibi geliyor bana,. Rakam aslında çok önemli değildir, ama eğer farklı öğeleri içeren bir liste oluşturmak için gerekli olan ancak, statik olarak kesin olarak bilinen türleri, ama bunların sayısı statik olarak bilmiyorsun Olası görünmemektedir.Soru 1:Hatta böyle bir örnek, örneğin, bir döngü içinde yazar mısınız? Benim sezgi keyfi elemanlarının statik olarak bilinmeyen bir numara (keyfi olarak verilen bir sınıfın göreli) ile statik olarak hassas bir hlist olan sadece uyumlu değil.

HLists vs Dizilerini

Eğer bu doğruysa, ben.e, statik olarak sayısı ve türüSoru 2:neden sadece n-kayıt düzeni kullanmıyorlar? Tabii, typesafely göster ve bir HList kat üzerinde olabilir de, ama . ( ^strong>değiltypesafely, productIterator) yardımıyla bir demet, ama eleman sayısı ve tipi statik olarak bilinir, çünkü muhtemelen sadece demet unsurları doğrudan erişim ve işlemleri gerçekleştirebilir.

İşlevi 8* *öte yandan, bir hlist tüm unsurları bunu kabul eder - bu çok genel üzerinde gösterSoru 3:neden productIterator.map) kullanmak değil mi? Tamam, ilginç bir fark edebilirsin yöntem aşırı yükleme: eğer biz vardı birkaç aşırı f'nın" sahip olma " güçlü tür tarafından sağlanan bilgileri hlist (aksine productİterator) olabilir izin derleyici seçimi için daha özel f. Ancak, eğer gerçekten yöntemleri ve işlevleri aynı değildir, çünkü Scala, eğer emin değilim.

HLists ve kullanıcı giriş

Elemanların sayısını ve türlerini bilmek gerekir ki aynı varsayım, yani, bina statik olarakSoru 4:hlists elemanları kullanıcı etkileşimi her türlü bağlı durumlarda kullanılabilir? E. g., bir döngü içinde elemanları ile bir hlist doldurma düşünün; elementlerin belirli bir koşul tutar kadar bir yere (UI, yapılandırma dosyası, oyuncu etkileşimi, ağ) okunur. Bu hlist türü ne olurdu? Benzer bir arabirim belirtimi getElements: HList[...] bu nedenle listeler statik olarak bilinmeyen uzunluğu, ve sağlayan Bir bileşen olarak bir sistem için böyle bir liste keyfi elemanları B. bileşeni

CEVAP
6 AĞUSTOS 2012, PAZARTESİ


Soru üç hitaben: HLists parametre üzerinde özetleme için temel uygulamalardan biri. Parametre genellikle statik bir soyutlama herhangi bir kullanım yerinde bilinir, ama siteden siteye değişir. examples, Bu, şekilsiz

def flatten[T <: Product, L <: HList](t : T)
  (implicit hl : HListerAux[T, L], flatten : Flatten[L]) : flatten.Out =
    flatten(hl(t))

val t1 = (1, ((2, 3), 4))
val f1 = flatten(t1)     // Inferred type is Int :: Int :: Int :: Int :: HNil
val l1 = f1.toList       // Inferred type is List[Int]

val t2 = (23, ((true, 2.0, "foo"), "bar"), (13, false))
val f2 = flatten(t2)
val t2b = f2.tupled
// Inferred type of t2b is (Int, Boolean, Double, String, String, Int, Boolean)

Kullanmadan HLists (veya buna benzer) soyut üzerinden parametre olan kayıt düzeni bağımsız flatten imkansız tek bir uygulama, bunun kabul argümanlar bu iki çok farklı şekil ve dönüşüm onları bir tür güvenli yolu.

Soyut olanağı sunar yere sabit arities ilgili ilgi çekici olması muhtemeldir: yanı sıra yöntem/içeren dizilerini yukarıdaki gibi fonksiyonu parametre listeleri ve dava sınıflar. Üzerinde keyfi bir durum sınıfları parametre türü sınıf örneklerini neredeyse otomatik olarak elde etmek için soyut olabilir nasıl örnekler için here bkz

// A pair of arbitrary case classes
case class Foo(i : Int, s : String)
case class Bar(b : Boolean, s : String, d : Double)

// Publish their `HListIso`'s
implicit def fooIso = Iso.hlist(Foo.apply _, Foo.unapply _)
implicit def barIso = Iso.hlist(Bar.apply _, Bar.unapply _)

// And now they're monoids ...

implicitly[Monoid[Foo]]
val f = Foo(13, "foo") | | Foo(23, "bar")
assert(f == Foo(36, "foobar"))

implicitly[Monoid[Bar]]
val b = Bar(true, "foo", 1.0) | | Bar(false, "bar", 3.0)
assert(b == Bar(true, "foobar", 4.0))

Çalışma zamanı yokyinelemeburada, ama yokçoğaltılması, HLists (ya da eşdeğeri yapılar) kullanımını ortadan kaldırabilir. Eğer tekrarlayan demirbaş için toleransı yüksek tabii ki, değer verdiğin her şekil için birden fazla uygulamaları yazarak aynı sonucu alabilirsiniz.

"... İşlevi eğer bir f hlist tüm unsurları bunu kabul eden çok genel üzerinde göster ... neden productİterator.) kullanmak değil üç soru göster?". Eğer bir HList üzerinde göster işlevi gerçekten formu Any => T sonra haritalama ise productIterator size çok iyi hizmet edecektir. Ama Any => T genellikle ilginç değil mi formun fonksiyonları (en azından, onlar sürece değiller tür dava dahili). şekilsiz türüne özgü tam şekilde davalar hakkında Eğer şüphe seçmek için derlemek sağlayan polimorfik fonksiyonu değeri bir form sağlar. Örneğin,

// size is a function from values of arbitrary type to a 'size' which is
// defined via type specific cases
object size extends Poly1 {
  implicit def default[T] = at[T](t => 1)
  implicit def caseString = at[String](_.length)
  implicit def caseList[T] = at[List[T]](_.length)
}

scala> val l = 23 :: "foo" :: List('a', 'b') :: true :: HNil
l: Int :: String :: List[Char] :: Boolean :: HNil =
  23 :: foo :: List(a, b) :: true :: HNil

scala> (l map size).toList
res1: List[Int] = List(1, 3, 2, 1)

Kullanıcı girişi hakkında soru dört ile ilgili olarak, dikkate alınması gereken iki durum vardır. İlk dinamik olarak bilinen statik bir durum almasını garanti eden bir bağlam kurabiliriz durumlar. Bu tip senaryolar içinde gayet Olası şekilsiz teknikleri, ama açıkça bu koşul ile statik durum geçerliyokalternatif bir yol izlemeliyiz sonra çalışma zamanında elde etmek. Şaşırtıcı olmayan bir şekilde, bu dinamik koşulları duyarlı olan yöntemler isteğe bağlı sonuçlar anlamına gelir. İşte size bir örnek HLists, kullanarak

trait Fruit
case class Apple() extends Fruit
case class Pear() extends Fruit

type FFFF = Fruit :: Fruit :: Fruit :: Fruit :: HNil
type APAP = Apple :: Pear :: Apple :: Pear :: HNil

val a : Apple = Apple()
val p : Pear = Pear()

val l = List(a, p, a, p) // Inferred type is List[Fruit]

l türü listenin uzunluğu, veya öğeleri belirli türleri ele geçirmiyor. Eğer belirli bir formu (yani. bekliyoruz ancak eğer bazı bilinen, sabit bir şema) uygun olmalı, o zaman bu gerçeği belirlemeye ve buna göre hareket edebiliriz

scala> import Traversables._
import Traversables._

scala> val apap = l.toHList[Apple :: Pear :: Apple :: Pear :: HNil]
res0: Option[Apple :: Pear :: Apple :: Pear :: HNil] =
  Some(Apple() :: Pear() :: Apple() :: Pear() :: HNil)

scala> apap.map(_.tail.head)
res1: Option[Pear] = Some(Pear())

Listesi verilen gerçek uzunluğunu, başka bir liste olarak aynı boyda fazla bir önemi olmayabilir diğer durumlar vardır. Yine bu destekler, tamamen statik olarak hem de karışık statik/dinamik bir bağlamda yukarıdaki gibi şekilsiz bir şey. Uzun bir örneğin here bkz.

Doğru olarak gözlemlemek, hepsi bu mekanizma gerektirir statik tür bilgi için kullanılabilir, en azından koşullu olarak, ve bunun gibi hariç bu teknikler olmaktan kullanışlı bir tamamen dinamik ortam, tamamen tahrik tarafından dışarıdan sağlanan veri yazılmamış. Ama gelişmesiyle desteği için çalışma zamanı derleme gibi bir bileşen Scala yansıması 2.10, hatta bu artık aşılamaz bir engel ... kullanabileceğimiz çalışma zamanı derleme sağlamak için bir form lightweight staging ve bizim statik yazarak yapılan çalışma zamanında yanıt olarak dinamik veri: alıntı dan önceki ... aşağıda takip linki için tam bir örnek

val t1 : (Any, Any) = (23, "foo") // Specific element types erased
val t2 : (Any, Any) = (true, 2.0) // Specific element types erased

// Type class instances selected on static type at runtime!
val c1 = stagedConsumeTuple(t1) // Uses intString instance
assert(c1 == "23foo")

val c2 = stagedConsumeTuple(t2) // Uses booleanDouble instance
assert(c2 == " 2.0")

@PLT_Borat bu konuda söyleyecek bir şeylerin vardır, onun belirli eminim sage comments about dependently typed programming languages ;-)

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • sebsebdouze

    sebsebdouze

    7 ŞUBAT 2008
  • TimMinchinLive

    TimMinchinLi

    23 ŞUBAT 2009
  • Yanko Kral

    Yanko Kral

    8 HAZİRAN 2006