Как прокомментировал Томас М. Дюбюссон, на самом деле это не очень хорошо выполнимо, поскольку длина списка известна только во время выполнения, но кортежи разной глубины имеют разные типы, а типы должны быть известны во время компиляции.
(Технически говоря, Haskell фактически может действовать как полный динамически типизированный язык, используя тип Data.Dynamic
, но это действительно непрактично для использования.)
Однако есть еще один способ сделать преобразование списков в кортежи разумного выхода: если вы делаете знаете во время компиляции, какая будет правильная глубина, а список с несоответствующей длиной должен просто быть неверным вводом,В этом случае вы можете использовать что-то вроде
{-# LANGUAGE FunctionalDependencies, FlexibleInstances #-}
class NestedTup e t where
toNestedTup :: [e] -> Maybe t
instance NestedTup e e where
toNestedTup [e] = Just e
toNestedTup _ = Nothing
instance NestedTup h t => NestedTup h (h,t) where
toNestedTup (h:t) = (h,)<$>toNestedTup t
toNestedTup [] = Nothing
*Main> toNestedTup [1,2,3,4 :: Int] :: Maybe (Int,(Int,(Int,Int)))
Just (1,(2,(3,4)))
*Main> toNestedTup [1,2,3,4,5 :: Int] :: Maybe (Int,(Int,(Int,Int)))
Nothing