Vay be, bu eski bir! Ben kodu biraz temizlemeye ve güncel deyimsel sözleşmeleri ile uyumlu içine çekerek başlayacağız:
case class Flat[T, U](fn: T => List[U])
implicit def recFlattenFn[T, U](
implicit f: Flat[T, U] = Flat((xs: T) => List(xs))
) = Flat((xs: List[T]) => xs flatMap f.fn)
def recFlatten[T, U](xs: List[T3])(implicit f: Flat[List[T], U]) = f fn xs
Sonra fazla uzatmadan, kod yıkmak.
case class Flat[T, U](fn: T => List[U])
Bu işlevin T => List[U]
için adlandırılmış sarıcı daha hiçbir şey, tip T
bir örneğini verildiğinde bir List[U]
inşa edecek bir işlevdir: Birincisi, bizim Flat
sınıf var. Burada T
'un da bir List[U]
veya U
veya List[List[List[U]]]
vb. Olabileceğini unutmayın. Normal olarak, böyle bir işlev doğrudan bir parametre tipi olarak belirtilebilir. Ancak, bunu örtük olarak kullanacağız, bu nedenle adlandırılmış sarmalayıcı örtük bir çakışma riskini önler. recFlatten
geriye çalışan sonra
:
def recFlatten[T, U](xs: List[T])(implicit f: Flat[List[T], U]) = f fn xs
Bu yöntem sunar xs
(a List[T]
) ve U
dönüştürecektir.
Bu
recFlatten
gerektirdiği örtük parametreyi tatmin
implicit def recFlattenFn[T, U](
implicit f: Flat[T, U] = Flat((xs: T) => List(xs))
) = Flat((xs: List[T]) => xs flatMap f.fn)
, o da başka bir örtülü parametrenin yeni sürer: Bunu başarmak için, o sonra gerçek büyü fn
Flat[T,U]
örtülü bir örneğini bulur ve kapalı işlevini çağırır . En önemlisi: bir Flat[T,U]
eğer T
bir List
olduğu gibi
recFlattenFn
kendi örtük parametre olarak hareket edebilir bir Düz döndürür
- [List [X], X], bu yüzden
recFlattenFn
yalnızca kesin olarak çözülecektir örtülü çözünürlük başarısız olursa
- örtük
f
Perha (yani T
bir List
dEĞİLDİR) varsayılan değer çare olabilir PS bu en iyi örneklerinden biri bağlamında anlaşılmalıdır:
örtülü arama bir 'Düz [Listesi için denenir tip T
List[List[Int]]
olarak anlaşılmaktadır recFlatten(List(List(1, 2, 3), List(4, 5)))
- [Liste [Uluslararası]], : Bu tarafından eşleştirilir
- U] yinelemeli konuşma Genel olarak
recFlattenFn
tanımlandığı Int
bir List
olmadığından [Int,_]
bu maçı başarısız parametreler recFlattenFn
sadece Flat[List[X], X]
için örtük bir arama ve türüyle uyumlu olacak
recFlattenFn[List[List[Int]], U] (f =
recFlattenFn[List[Int], U] (f =
Flat[Int,U]((xs: T) => List(xs)) //default value
)
)
Not. Bu, varsayılan değere geri dönüşü tetikleyen şeydir.
Tip çıkarsama da özyineleme her seviyede U
param çözme, o yapının kadar geriye çalışır:
Flat
durumlarda sadece bir yuvalama olup recFlattenFn[List[List[Int]], Int] (f =
recFlattenFn[List[Int], Int] (f =
Flat[Int,Int]((xs: T) => List(xs)) //default value
)
)
, bir flatMap
performans (en içteki hariç) her biri iç içe geçmiş List
yapısının bir düzeyini açmak için işlem. En içteki Flat
tüm tek tek elemanları tek bir List
içerisinde yedekler.
Q.E.D.
Çok yardımcı olan çok teşekkür ederim. Örneğinizde, tip parametrelerinin bir kaydırma ile kapalı olduğunu düşünüyorum. Bu, recFlatten [Liste [Int], Int] derler (Liste (Liste (1, 2, 3), Liste (4, 5))) ( recFlattenFn [Liste [Int], Int] (f = recFlattenFn [Int , Uluslararası] (f = Düz [Orta, Orta] ((xs: Int) => Liste (xs)) // varsayılan değer ) ' – huynhjl
Çok doğru, artık güncellenmiş ) ) :) –