Shapeless'ta Nat tipinin sınırları


151

Biçimsiz olarak, Nat türü, doğal sayıları bir tür düzeyinde kodlamanın bir yolunu temsil eder. Bu, örneğin sabit boyutlu listeler için kullanılır. Tür düzeyinde hesaplamalar bile yapabilirsiniz, örneğin, bir Nöğe listesine bir öğe listesi ekleyebilir ve öğeleri Kderleme zamanında bilinen bir listeyi geri alabilirsiniz N+K.

Bu gösterim, örneğin 10000002 53 gibi büyük sayıları temsil edebilecek mi yoksa Scala derleyicisinin pes etmesine neden olacak mı?


21
Miles'ın NE Scala sunumu geçen yıl adresleri bu soru ve kısa cevap o Scala-veya en az 2.10-kullanmada tür düzeyinde çok sayıda temsil etmek mümkün olacağıdır türleri tekil , ancak buna değer olmayabilir . Shapeless 2.0 şu anda hala Kilise kodlamasını kullanıyor ve bu da derleyiciden vazgeçmeden 1000'e kadar çıkmanızı sağlıyor.
Travis Brown

3
Bugün daha sonra biraz daha bağlamla bir cevap yazmaya çalışacağım. Bir yan not olarak, daha büyük tip seviyesi sayılarına ihtiyacınız varsa tamsayı singleton türleriyle çalışmak çok zor değildir; örneğin, blog yazımı buraya veya Shapeless'daki singleton işlevselliğine bakın .
Travis Brown

2
Büyük tür düzeyindeki sayılar üzerinde aritmetik yapmak istiyorsanız, bunları bağlantılı bitler listesi olarak uygulamayı düşünebilirsiniz.
Karol S

1
@KarolS Bu stratejinin bir uygulaması var! Ve kimse ilgileniyorsa şekilsiz katkıda bulunmaktan memnuniyet duyarım, ancak birisi stackoverflow.com/questions/31768203/…
beefyhalo

2
Görünüşe göre stackoverflow.com/questions/31768203/… çözüldü, bu yüzden size kod katkıda bulunabilir ve soruyu kendi yanıtınızla kapatabilir misiniz?
Andriy Kuba

Yanıtlar:


17

Kendim denerim. Travis Brown veya Miles Sabin'den daha iyi bir cevap memnuniyetle kabul edeceğim.

Nat anda olabilir değil çok sayıda temsil etmek için kullanılabilir

Nat'in şu anki uygulamasında, değer iç içe biçimli şekilsiz.Succ [] türlerinin sayısına karşılık gelir:

scala> Nat(3)
res10: shapeless.Succ[shapeless.Succ[shapeless.Succ[shapeless._0]]] = Succ()

Yani 1000000 sayısını temsil etmek için, 1000000 derinlikte iç içe geçmiş bir tipiniz olacak ve bu kesinlikle scala derleyicisini havaya uçuracaktır. Mevcut sınır denemeden yaklaşık 400 gibi görünüyor, ancak makul derleme süreleri için muhtemelen 50'nin altında kalmak en iyisi olacaktır.

Ancak, büyük tam sayıları veya diğer değerleri tür düzeyinde kodlamak için bir yol vardır, ancak bunlar üzerinde hesaplamalar yapmak istemezsiniz . Bildiğim kadarıyla bunlarla yapabileceğiniz tek şey, eşit olup olmadıklarını kontrol etmektir. Aşağıya bakınız.

scala> type OneMillion = Witness.`1000000`.T
defined type alias OneMillion

scala> type AlsoOneMillion = Witness.`1000000`.T
defined type alias AlsoOneMillion

scala> type OneMillionAndOne = Witness.`1000001`.T
defined type alias OneMillionAndOne

scala> implicitly[OneMillion =:= AlsoOneMillion]
res0: =:=[OneMillion,AlsoOneMillion] = <function1>

scala> implicitly[OneMillion =:= OneMillionAndOne]
<console>:16: error: Cannot prove that OneMillion =:= OneMillionAndOne.
       implicitly[OneMillion =:= OneMillionAndOne]
                 ^

Bu, Array [Byte] üzerinde bit işlemleri yaparken aynı dizi boyutunu uygulamak için kullanılabilir.


Sadece bu cevabı gördüm ve +1, bu iyi bir örnek. Bunu gerçi belirterek It değerinde olabilir mesela Biçimsizler en gibi tip sınıfları sağlamakops.nat.Sum olduğunu (onlar sadece bir makro tarafından sağlanacak olurdu) iki tip düzey tamsayılar, belirli bir miktar, vb vardı şahit olacaktır.
Travis Brown

1
Aşağıda , Concatmakro ile iki tür düzeyindeki dizeyi birleştirmeye izin veren bir tür sınıfına örnek verilmiştir . Tür düzeyi tamsayıları toplamak için bir tür sınıfı muhtemelen çok benzer görünecektir.
Frank

5

Shapeless's Natdoğal sayıları Kilise kodlaması kullanarak tür düzeyinde kodlar. Alternatif bir yöntem, doğalları bir bit seviyesi HList listesi olarak göstermektir.

Bu çözümü şekilsiz bir tarzda uygulayan yoğun göz atın .

Bir süredir üzerinde çalışmadım Lazyve skala vazgeçtiği zaman için burada ve orada şekilsiz bir serpme gerekiyor, ancak kavram sağlam :)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.