Конвертировать список во вложенный кортеж Haskell - PullRequest
3 голосов
/ 03 ноября 2019

Короче говоря, моя проблема в том, что я анализирую список чисел ([Integer]) и хочу преобразовать этот список во вложенные кортежи, поэтому, например, список [1,2,3,4] будетbe (1, (2, (3,4))) это мне кажется выполнимым с помощью операции сгиба. Я думаю, что проблема, с которой я сталкиваюсь, заключается в том, что тип не определен заранее, что делает гнездо кортежа потенциально бесконечным.

РЕДАКТИРОВАТЬ НА ОСНОВЕ КОММЕНТАРИЙ

Спасибо за хорошие ответы, корень проблемы в назначении, поэтому подробности о более серьезной проблеме редки, но в попытке не оставить васинтересно, я могу немного расширить, хотя я не ищу ответы на расширение. Моя проблема сводится к проблеме с правильной рекурсивной и правильной ассоциативной частью грамматики без контекста, где у меня есть что-то вроде

A -> n A

, чтобы я мог получить выражение вродетаким образом, 'nnnn A', который разбирает на 'n (n (n (n A)))' (A имеет другие терминалы). Я могу разобрать его в '[n, n, n, n] A', поэтому я и захотел преобразование (я знаю, что есть лучший способ, я просто изо всех сил пытаюсь его найти).

1 Ответ

5 голосов
/ 03 ноября 2019

Как прокомментировал Томас М. Дюбюссон, на самом деле это не очень хорошо выполнимо, поскольку длина списка известна только во время выполнения, но кортежи разной глубины имеют разные типы, а типы должны быть известны во время компиляции.

(Технически говоря, 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...