Как может я лучше всего преобразовывать список в кортеж в Haskell:
[1,2,3,4,5,6] -> (1,2,3,4,5,6)
В общем случае, вы не можете. Кортеж каждого размера является отдельным типом, в то время как списки любой длины являются одним типом. Таким образом, нет хорошего способа написать функцию, которая принимает список и возвращает кортеж той же длины - у нее не будет четко определенного возвращаемого типа.
Например, вы можете иметь функции типа:
tuplify2 :: [a] -> (a,a)
tuplify2 [x,y] = (x,y)
tuplify3 :: [a] -> (a,a,a)
tuplify3 [x,y,z] = (x,y,z)
... но не одну, которая выполняла бы обе функции.
Вы можете написать общую версию, используя различные виды метапрограммирования, но вы редко захотите это делать.
Обратите внимание, что та же проблема относится и к другим вещам, например, к написанию экземпляров классов для различных кортежей - взгляните на исходный код Data.Tuple из стандартных библиотек!
Шаблонный Haskell настолько близок, насколько это возможно благодаря проверке типов, если вы хотите извлечь переменное количество элементов, поскольку (a,b) и (a,b,c) имеют разные типы.
{-# LANGUAGE TemplateHaskell #-}
import Language.Haskell.TH
tuple :: Int -> ExpQ
tuple n = do
ns <- replicateM n (newName "x")
lamE [foldr (\x y -> conP '(:) [varP x,y]) wildP ns] (tupE $ map varE ns)
Тогда:
$(tuple 6) [1,2,3,4,5,6] == (1,2,3,4,5,6)
$(tuple 3) "abc" == ('a','b','c')
Но вообще, если вам нужен такой ответ, значит, вы где-то задаете неправильный вопрос.
Если вам нужен просто плоский произвольный доступ, то, возможно, лучшим вариантом будет использование массива.
На самом деле вы можете добиться большего успеха, чем вручную писать одну функцию для каждого размера кортежа, если вы используете квазициктирование , как описано здесь . Однако я бы поинтересовался кодом, в котором вы ожидаете использовать это в целом.
Кортежи и списки - это очень разные вещи. Лучшее, что вы можете сделать, это вручную написать функцию преобразования:
toTuple :: [a] -> (a,a,a,a,a,a)
toTuple [a,b,c,d,e,f] = (a,b,c,d,e,f)
Обратите внимание, как отличаются типы: одна переменная списка расширяется до шести переменных кортежа. Поэтому вам понадобится одна функция для каждого размера кортежа.