Я действительно заинтересован в том, чтобы выяснить, где существуют различия, и, в более общем плане, выявить канонические случаи использования, в которых нельзя использовать списки HL (или, скорее, не давать никаких преимуществ по сравнению с обычными списками).
(Я знаю, что TupleN
в Scala есть 22 (я полагаю) , тогда как нужен только один HList, но это не та концептуальная разница, которая меня интересует.)
Я отметил пару вопросов в тексте ниже. На самом деле, возможно, нет необходимости отвечать на них, они предназначены для того, чтобы указывать на вещи, которые мне неясны, и направлять обсуждение в определенных направлениях.
мотивация
Недавно я видел пару ответов на SO, где люди предлагали использовать HLists (например, предоставленные Shapeless ), включая удаленный ответ на этот вопрос . Это привело к этой дискуссии , которая в свою очередь породила этот вопрос.
вступление
Мне кажется, что списки полезны только тогда, когда вы знаете количество элементов и их точные типы статически. Число на самом деле не имеет решающего значения, но кажется маловероятным, что вам когда-либо понадобится создать список с элементами различных, но статически точно известных типов, но вы не будете знать статически их количество. Вопрос 1: Вы могли бы даже написать такой пример, например, в цикле? Моя интуиция заключается в том, что наличие статически точного списка hlist со статически неизвестным числом произвольных элементов (произвольных относительно данной иерархии классов) просто несовместимо.
HLists vs. Tuples
Если это так, т.е. вы статически знаете число и тип - Вопрос 2: почему бы просто не использовать n-кортеж? Конечно, вы можете безопасно отображать и сворачивать HList (который вы можете, но не безопасно, делать поверх кортежа с помощью productIterator
), но так как число и тип элементов статически известны, вы, вероятно, можете просто получить доступ к элементам кортежа непосредственно и выполнять операции.
С другой стороны, если функция, которую f
вы отображаете над списком, является настолько общей, что она принимает все элементы - Вопрос 3: почему бы не использовать ее через productIterator.map
? Хорошо, одно интересное отличие может быть f
связано с перегрузкой метода: если бы у нас было несколько перегруженных , наличие более сильной информации о типе, предоставляемой hlist (в отличие от productIterator), могло бы позволить компилятору выбрать более конкретный вариант f
. Однако я не уверен, что это действительно сработает в Scala, поскольку методы и функции не одинаковы.
HLists и пользовательский ввод
Основываясь на том же предположении, а именно, что вам нужно знать число и типы элементов статически - Вопрос 4: можно ли использовать списки в ситуациях, когда элементы зависят от любого вида взаимодействия с пользователем? Например, представьте, что hlist заполняется элементами внутри цикла; элементы читаются откуда-то (пользовательский интерфейс, файл конфигурации, взаимодействие с актером, сеть), пока не выполнится определенное условие. Каким будет тип списка? Аналогично для спецификации интерфейса getElements: HList [...], которая должна работать со списками статически неизвестной длины и которая позволяет компоненту A в системе получать такой список произвольных элементов из компонента B.
FunctionN
черты не знаю , как абстрагироваться над арностью: github.com/paulbutcher/ScalaMock/blob/develop/core/src/main/... github.com/paulbutcher/ScalaMock/blob / разработки / ядро / SRC / главная / ... к сожалению , я не знаю ни одного способа , который можно использовать бесформенные , чтобы избежать этого, учитывая , что мне нужно иметь дело с «реальным»FunctionN
sПросто чтобы быть понятным, HList - это, по сути, не что иное, как стопка
Tuple2
с немного отличающимся сахаром сверху.Таким образом, ваш вопрос, по сути, касается различий между использованием вложенных кортежей и плоских кортежей, но оба они изоморфны, так что в итоге нет никакой разницы, кроме удобства в том, какие библиотечные функции можно использовать и какие нотации можно использовать.
источник
Есть много вещей, которые вы не можете сделать (хорошо) с кортежами:
Конечно, вы можете делать все это с помощью кортежей, но не в общем случае. Таким образом, использование HLists делает ваш код более сухим.
источник
Я могу объяснить это на супер простом языке:
Наименование «кортеж против списка» не имеет значения. HLists можно назвать HTuples. Разница в том, что в Scala + Haskell вы можете сделать это с помощью кортежа (используя синтаксис Scala):
взять входной кортеж ровно из двух элементов любого типа, добавить третий элемент и вернуть полностью типизированный кортеж с ровно тремя элементами. Но в то время как это является полностью общим для типов, оно должно явно указывать длину ввода / вывода.
Что позволяет сделать HList в стиле Haskell, так это сделать его универсальным по длине, чтобы вы могли добавлять к любой длине кортежа / списка и возвращать полностью статически типизированный кортеж / список. Это преимущество также применимо к однородно типизированным коллекциям, где вы можете добавить int к списку из ровно n целых и вернуть список, который статически типизирован, чтобы иметь ровно (n + 1) целые числа без явного указания n.
источник