创建一个 IO 字符串

Create an IO string

出于某种原因,getLine 在我的 Jupiter 笔记本中不起作用。有什么方法可以人为地创建一个 IO 字符串,以便我可以继续一些需要它的示例吗?

我试过这样的事情:

main = do
    foo :: IO String
    foo << "sdf"
   

但显然没有奏效。有什么办法吗? 谢谢!

类型 IO String 的值表示可以执行一些 IO 并在执行时产生 String 的操作(最终,来自 main)。通常,getLine 是从“标准输入”(stdin)读取一行文本的操作。如果您只想使用 您自己的 操作而不是 getLine,您可以使用 pure :: (Applicative f) => a -> f a 非常简单地构造一个,其中 fIOa 在这种情况下是 String

fakeGetLine :: IO String
fakeGetLine = pure "always the same string"

旁白:由于历史原因,pure 也称为 return :: (Monad m) => a -> m a,但没有必要使用它,因为它是相同的函数,但名称更长,类型稍微受限一些。

现在,您可以将输入 getLine 的任何位置替换为 fakeGetLinepure "whatever string you wish to use" 等表达式。同样,如果你需要一个常量 IO Int,你可以使用 pure 123pure (123 :: Int).

您不能替换标准 getLine,但可以使用与 getLine 相同的 name 自己的定义,前提是您使用 importhiding 声明从范围中隐藏默认值:

import Prelude hiding (getLine)

getLine :: IO String
getLine = pure "always the same string"

或者,您实际上可以在 IPython 笔记本中读取 stdin,只要您使用支持“输入请求”功能的前端打开它,例如 JupyterLab or Deepnote. To the best of my knowledge, this is not currently supported in Hydrogen, nteract, or Spyder.

最后,Python 中有时针对此问题推荐的方法 不适用于 Haskell,它正在尝试替换 stdin 使用不同的句柄。该技术在 Python 中是可能的,因为它的 stdin 是一个 可变的 变量,而在 Haskell、stdin 中(像所有变量一样) 不可变.