【问题标题】:Haskell IO String -> String [duplicate]Haskell IO字符串->字符串[重复]
【发布时间】:2021-10-18 02:33:46
【问题描述】:

我有以下功能:

getBoard :: String
getBoard = do
    contents <- readFile "src/board.txt"
    return contents

我收到了这个错误:

• 无法将类型“IO”与“[]”匹配 预期类型:[字符串] 实际类型:IO String

已经在互联网上阅读了很多东西,显然我的代码应该可以工作。谁能告诉我怎么了?

Obs:当我去 repl 做:

contents <- readFile "src/board.txt"

然后:

:type contents

它告诉我内容是一个字符串。所以,我无法弄清楚为什么我会收到上面提到的错误。

注意:getBoard 函数必须返回一个字符串

【问题讨论】:

  • 你也可以向repl询问return的类型。在 Haskell 中,return 只是一个函数。它的类型是:return :: Monad m =&gt; a -&gt; m a。现在的问题是:您想要或期望哪个 monad?
  • 你的意思是我需要另一个类型为 IO String -> String 的函数?
  • @ThallesPortilho 类型系统不会让您在函数中产生任意副作用:“getBoard 函数必须返回一个字符串”它实际上不能。或者换一种说法,如果你想让一个函数返回一个纯字符串,它不能从文件(或 STDIN,或...)中读取它。
  • @ThallesPortilho 好吧,库中存在IO a -&gt; a 类型的多态函数。 Hoogle 会很乐意为您指出它,这是unsafePerformIO。但线索就在名字里。例如,如果您使用getLineunsafePerformIO,您将始终阅读同一行,因为引用透明older question 中的详细信息由结束您的问题的人指出

标签: haskell


【解决方案1】:

你写过:

getBoard :: String

这并不是说getBoard 是一个返回String 的函数或过程。相反,它说getBoard String;我的意思是一些特定的String,例如"Hello world""foo"。显然,这是错误的。相反,getBoard 是一个您可以执行的过程,它会产生一个String 作为其结果。在 Haskell 中,你这样说是:

getBoard :: IO String

所以这是正确的答案。如果该答案不适合您,请提供更多背景信息,以便我们了解原因。

当您说“注意:getBoard 函数必须返回一个字符串”时,这几乎就是 getBoard :: IO String 的意思:getBoard 是一个返回 String 的过程。 (这里有一个微妙的点是我说的是“过程”而不是“函数”。那是因为在 Haskell 中,“函数”的含义与您可能对其他语言的期望不同。函数是带有参数的东西。因为getBoard 不带参数,所以它不是函数,而是过程。)

您的意思是希望它成为String,而不是返回一个?不过,这没有多大意义。您希望是哪个具体的String


好的,现在我不情愿地承认,有一种方法可以(错误地)告诉 Haskell getBoardString。你不应该这样做,除非你是一个非常高级的 Haskell 程序员,理解其中的含义,并且有充分的理由这样做是值得的。但是您可以导入System.IO.Unsafe,然后使用unsafePerformIO 函数包装getBounds 的定义。这句话的意思是:“假设getBounds 是某个特定的String,而不是一个程序。任何时候你需要知道它是哪个String,偷偷溜到幕后运行这个程序来找出答案。”

请注意,如果您这样做,则无法保证您的程序何时读取文件,程序读取文件的次数,甚至您的程序是否会读取文件!所有这些都取决于评估的严格性、编译器内联等优化选择等等。如果在程序运行时文件的内容发生了变化,结果是不确定的。这不是编写 Haskell 的正常方式,其他 Haskell 程序员会给你奇怪的表情,并认为如果你没有充分理由这样做,你会有点无知,你可能应该忘记它直到你更先进。我只是提到它,因为我不想给出不完整的回答。

【讨论】:

    猜你喜欢
    • 2011-10-01
    • 2013-05-01
    • 2011-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多