Нахождение способов подделать подобные вещи с помощью системных трюков с переобработанным типом - одно из моих хобби, поэтому поверьте мне, когда я скажу, что результат довольно уродливый. В частности, обратите внимание, что кортежи не определены рекурсивно, поэтому нет реального способа абстрагироваться над ними напрямую; Что касается системы типов Haskell, то каждый размер кортежа совершенно различен.
Поэтому любой жизнеспособный подход для работы с кортежами потребует генерации кода - либо с использованием TH, либо внешнего инструмента, как в пакете tuple
.
Чтобы подделать его без использования сгенерированного кода, вы должны сначала прибегнуть к использованию рекурсивных определений - обычно это пары с правым вложением со значением «nil» для обозначения конца, либо (,)
и ()
или что-то эквивалентное их. Вы можете заметить, что это похоже на определение списков в терминах (:)
и []
- и на самом деле рекурсивно определенные искусственные кортежи такого рода можно рассматривать как структуры данных на уровне типа (список типы) или как разнородные списки (например, HList работает таким образом).
Недостатки включают, помимо прочего, тот факт, что на самом деле с использованием вещей, созданных таким образом, может быть более неуклюжим, чем стоит, код для реализации уловок системы типов, как правило, сбивает с толку и совершенно не -портативно, и конечный результат не обязательно эквивалентен в любом случае - например, существует множество нетривиальных различий между (a, (b, (c, ())))
и (a, b, c)
.
Если вы хотите увидеть, как это ужасно, вы можете посмотреть материал, который у меня есть на GitHub , в частности биты здесь .