Как изменить базовый вариант, чтобы началась рекурсия?

Я пытаюсь заставить рекурсию работать бесконечно для моего проекта. Это мой код:

putStr' :: String -> IO ()
putStr' (a:as) = do putChar a
                    putChar '\n'
                    threadDelay 1000000
                    putStr' as
putStr' []     = putStr'

выдает эту ошибку

<interactive>:339:18: error:
    * Couldn't match expected type: IO ()
                  with actual type: String -> IO ()
    * Probable cause: putStr' is applied to too few arguments
      In the expression: putStr'
      In an equation for putStr': putStr' [] = putStr'

Я тоже это попробовал

putStr' :: String -> IO ()
putStr' (a:as) = do putChar a
                    putChar '\n'
                    threadDelay 1000000
                    putStr' as
putStr' []     = putStr' (a:as)

но безрезультатно, как он мне говорит:

<interactive>:297:27: error: Variable not in scope: a :: Char

<interactive>:297:29: error: Variable not in scope: as :: [Char]

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

Установите putStr' [] = pure (), а затем используйте forever (putStr' s).

Naïm Favier 27.07.2024 16:57

«Я знаю, что вам не следует этого делать, поскольку это может быть опасно, но на самом деле это то, что мне нужно, чтобы мой код работал». – Пожалуйста, не описывайте попытку решения, а опишите реальную проблему, чтобы избежать проблемы XY.

cafce25 27.07.2024 18:18
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
65
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Не думайте о вечном цикле; подумайте о цикле по списку, который может быть или не быть бесконечным, а затем предоставить бесконечный список.

putStr' :: String -> IO ()
putStr'  = traverse_ go . cycle  where
    go x = do putChar x
              putChar '\n'
              threadDelay 1000000

Скучное базовое решение — добавить второй аргумент, который никогда не меняется, чтобы мы могли «сбросить» первый аргумент по мере необходимости.

putStr'2 :: String -> String -> IO ()
putStr'2 (a:as) bs = do putChar a
                        putChar '\n'
                        threadDelay 1000000
                        putStr'2 as bs
putStr'2 []     bs = putStr'2 bs bs

putStr' :: String -> IO ()
putStr' as = putStr'2 as as

Это далеко не элегантно, но для понимания не требуется сложных концепций.

Использование внутреннего определения также является относительно простым.

putStr' :: String -> IO ()
putStr' bs = putStr'2 bs
   where
   putStr'2 :: String -> IO ()
   putStr'2 (a:as) = do putChar a
                        putChar '\n'
                        threadDelay 1000000
                        putStr'2 as
   putStr'2 []     = putStr'2 bs

Другие вопросы по теме