【问题标题】:Haskell file I/O return types not matching?Haskell 文件 I/O 返回类型不匹配?
【发布时间】:2018-02-28 06:56:40
【问题描述】:

转发通知,这是我使用 Haskell 的第一天。

所以我有一个函数parse :: String -> String,我正试图通过标准将文件传递给它,

input <- readFile "input.txt"

或其他标准,

handle <- openFile "input.txt" ReadMode
input <- hGetContents handle

我想表演的,

output <- unlines $ map parse $ lines input

(或者应该是规范格式)
现在据我了解, readFile 返回一个字符串,lines 接受一个字符串并返回一个字符串列表,并且 map 应该映射到一个字符串列表。如果这是真的,那么为什么lines input 告诉我得到了一个 [String] 而不是一个 String,而省略了 lines 而只有 map parse input 告诉我它得到了一个 String 而不是一个 [String]?

【问题讨论】:

  • “readFile 返回一个字符串”。不,it doesn't
  • @MarkSeemann 好吧,函数不会返回字符串,但它会“返回”IO 隐喻意义上的字符串。
  • 您似乎不了解 monad 和 do-notation 的工作方式。我可以建议阅读the relevent LYAH chapter?
  • @AJFarmar 他们声称这是他们使用 Haskell 的第一天。如果他们知道 Monad 和 do 表示法的工作原理,我会感到震惊。
  • LYAH IO chapter 可能更有用。

标签: haskell


【解决方案1】:

这是工作示例

parse :: String -> String
parse = id -- don't do anything to input

main = do
    input <- readFile "input.txt"
    let output = unlines $ map parse $ lines input
    print output

在您的示例中,除了 output &lt;- 之外,一切都很好,应该用 let output = 替换,原因可能是您可能还不知道,根据您的措辞判断:readFile 返回一个字符串。正如在 cmets 中指出的那样,事实并非如此。它返回IO String,这意味着您可以启动一个 IO-action 并获取一个字符串(或者不...如果文件不存在)。 &lt;- 操作可让您检查此操作的积极结果:它表示当操作成功时,您会得到一个字符串(您称之为input)。然后你就可以玩它了。

那么为什么&lt;- 不适合在第二行(带有linesmap 等等)?很简单,因为里面没有动作。您正在那里应用 纯函数。通过let smth = 绑定纯计算的结果。

另外,请注意&lt;-let X = 属于do-blocks,句法结构旨在编写一系列步骤来处理动作。相比之下,在纯函数中,您可以找到let X = … in(注意in)或where X = 来绑定中间结果。

【讨论】:

  • 值得指出的是,此语法do 块(和 ghci)中有效 - 在其他任何地方都是 let x = ... in
  • 嘿嘿,就是这样。谢谢你。我想我从未与 do-block 建立联系。
猜你喜欢
  • 2014-03-02
  • 1970-01-01
  • 2018-07-24
  • 1970-01-01
  • 1970-01-01
  • 2021-03-07
  • 2021-03-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多