Naprawdę jestem zainteresowany ustaleniem, gdzie są różnice, a bardziej ogólnie, zidentyfikowaniem kanonicznych przypadków użycia, w których HLists nie mogą być używane (a raczej nie dają żadnych korzyści w porównaniu do zwykłych list).
(Zdaję sobie sprawę, że TupleN
w Scali jest 22 (wierzę) , podczas gdy potrzebna jest tylko jedna lista HList, ale nie jest to rodzaj różnicy pojęciowej, która mnie interesuje.)
W poniższym tekście zaznaczyłem kilka pytań. Właściwie może nie być konieczne odpowiadanie na nie, mają one raczej na celu wskazanie rzeczy, które są dla mnie niejasne, i ukierunkowanie dyskusji w określonych kierunkach.
Motywacja
Niedawno widziałem kilka odpowiedzi na SO, w których ludzie sugerowali użycie HLists (na przykład dostarczonych przez Shapeless ), w tym usuniętą odpowiedź na to pytanie . To dało początek tej dyskusji , która z kolei wywołała to pytanie.
Intro
Wydaje mi się, że hlisty są przydatne tylko wtedy, gdy znasz statycznie liczbę elementów i ich dokładne typy. Liczba w rzeczywistości nie jest kluczowa, ale wydaje się mało prawdopodobne, że kiedykolwiek będziesz musiał wygenerować listę z elementami różnych, ale statystycznie precyzyjnie znanych typów, ale nie znasz ich liczby. Pytanie 1: Czy mógłbyś w ogóle napisać taki przykład, np. W pętli? Moja intuicja jest taka, że posiadanie statycznie precyzyjnej listy hlist ze statycznie nieznaną liczbą dowolnych elementów (dowolnych względem danej hierarchii klas) po prostu nie jest kompatybilne.
HLists vs. krotki
Jeśli to prawda, tzn. Statycznie znasz liczbę i typ - Pytanie 2: dlaczego po prostu nie użyć n-krotki? Jasne, możesz bezpiecznie mapować i zawijać HList (co możesz również, ale nie typowo, zrobić w krotce za pomocą productIterator
), ale ponieważ liczba i typ elementów są znane statycznie, prawdopodobnie możesz po prostu uzyskać dostęp do elementów krotki bezpośrednio i wykonać operacje.
Z drugiej strony, jeśli funkcja, f
którą mapujesz na hlistę, jest tak ogólna, że akceptuje wszystkie elementy - Pytanie 3: dlaczego nie użyć jej za pośrednictwem productIterator.map
? Ok, jedna interesująca różnica może wynikać z przeciążenia metody: gdybyśmy mieli kilka przeciążonych f
, posiadanie silniejszej informacji o typie dostarczonej przez hlist (w przeciwieństwie do productIterator) mogłoby pozwolić kompilatorowi na wybranie bardziej szczegółowego f
. Nie jestem jednak pewien, czy to faktycznie zadziała w Scali, ponieważ metody i funkcje nie są takie same.
HLists i dane wejściowe użytkownika
Opierając się na tym samym założeniu, a mianowicie, że musisz znać liczbę i typy elementów statycznie - Pytanie 4: czy hlisty mogą być używane w sytuacjach, gdy elementy zależą od dowolnego rodzaju interakcji użytkownika? Np. Wyobraź sobie wypełnianie hlist elementów wewnątrz pętli; elementy są odczytywane skądś (interfejs użytkownika, plik konfiguracyjny, interakcja aktora, sieć), dopóki nie zostanie spełniony określony warunek. Jaki byłby typ listy hlist? Podobnie jest w przypadku specyfikacji interfejsu getElements: HList [...], która powinna działać z listami o statycznie nieznanej długości i która umożliwia komponentowi A w systemie uzyskanie takiej listy dowolnych elementów z komponentu B.