尝试在 ghci 输出中设置一些顺序

Trying to put some order in ghci output

出于教学目的,我正在尝试遵循并实施 IO inside

这个想法是表达一个类型 MIO a ("my 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)

之后我尝试定义几种与用户交互的方式,比如问一个或多个问题。整个代码是here.

已经从 getString 开始,我得到了一个非常有趣的输出:

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

我看到 getString 的结果是正确的,但是屏幕变得很乱。 Asking questions 让它变得更加混乱。

getString 的情况下,我希望最初的 (" 与最终结果一起出现。在ghci中有可能吗? (我怀疑,但我还是问了)

当我学习 these same matters in JavaScript 时,事情变得更容易了,因为我可以从浏览器中免费获得弹出窗口。是否有一些 Haskell-ready 环境可以插入我的代码?

我知道通过使用 unsafePerformIO 我已经让我的灵魂陷入永恒的痛苦中,但提醒我这将与我无关。

你的问题很容易解决seq

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

看:

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

这有多酷?

但我还想稍微推动一下您的要求:您可以将您的元组设为 monad 吗? (提示:您需要以某种方式修改它。) 然后您可以使用 do 符号,您的 RW IO 将看起来就像真实的东西!

P.S. 正如@chi 在评论中指出的那样,当您希望确保顺序时,您应该更喜欢 pseqThere is a veritable wall written about it on Haskell Wiki.