Попытка навести порядок в выводе ghci - PullRequest
4 голосов
/ 12 октября 2019

В дидактических целях я пытаюсь следовать и реализовать IO внутри .

Идея состоит в том, чтобы выразить тип MIO a ("мой IO"), который является RW -> (a, RW).

RW - это реальный мир, и для простоты это просто целое число;Я не могу использовать реальный RealWorld, потому что вокруг нет конструкторов.

Первые строки, которые я придумаю:

type RW = Integer

putString :: String -> RW -> ((), RW)
putString str world = (unsafePerformIO $ putStrLn str, world + 1)

getString :: RW -> (String, RW)
getString world = let input = unsafePerformIO getLine
  in (input, world + 1)

После этого я пытаюсь определить несколько способоввзаимодействовать с пользователем, например, задавая один или несколько вопросов. Весь код здесь .

Уже начиная с getString я получаю очень забавный вывод:

*Main> getString 0
("This is my input
This is my input",1)
*Main>

Я вижу, что результат getString правильный, но экран становится грязным. Задавать вопросы делает его еще более запутанным.

В случае getString Я бы хотел, чтобы начальные значения (" совпали с конечным результатом. Возможно ли это в ghci? (Я сомневаюсь в этом, но все равно спрашиваю)

Когда я изучал эти же вопросы в JavaScript , все было проще, потому что я мог бесплатно получать всплывающие окна из браузера. Есть ли какая-нибудь среда, готовая для Haskell, где я мог бы подключить свой код?

Я знаю, что с помощью unsafePerformIO я проклял свою душу вечным страданиям, но напомнил мне, что это будет не в моей точке.

1 Ответ

3 голосов
/ 12 октября 2019

Ваша проблема легко решается с помощью seq.

getString :: RW -> (String, RW)
getString world =
  let input = unsafePerformIO getLine
  in input `seq` (input, world + 1)

Вот:

λ getString 0
Hello!
("Hello!",1)

Насколько это круто?

Но я хочу такжеподтолкнуть вас к тому, что вы спрашиваете: можете ли вы сделать свой кортеж монадой? (Подсказка: вам нужно каким-то образом изменить его.) Тогда вы можете использовать do нотацию, и ваш RW IO будет выглядеть так же, как реальная вещь!

PS Как отмечает @chi в комментарии, вам следует предпочесть pseq, когда вы хотите обеспечить порядок. На Haskell Wiki об этом написана настоящая стена.

...