将配置文件读入 Haskell 时的战斗 IO

Fighting IO when reading a configuration file into Haskell

我有输入数据用于我尚未编写的 Haskell 应用程序,这些数据位于一个文件中。我不更新文件。我只需要读取文件并将其输入我的 Haskell 函数,该函数需要一个字符串列表。但是读取文件当然会产生 IO 个数据对象。我了解到使用 <- 操作可以 "take out" 以某种方式将字符串打包在 IO 结构中,所以我尝试了这个尝试:

run :: [String]
run = do
  datadef_content <- readFile "play.txt" -- yields a String
  let datadef = lines datadef_content -- should be a [String]
  return datadef

我将其放入文件 play.hs 并通过

从 ghci 加载它
:l play

令我惊讶的是,我收到了 readFile 行的错误消息

 Couldn't match type ‘IO’ with ‘[]’
 Expected type: [String]
   Actual type: IO String

对于 return 错误消息

 Couldn't match type ‘[Char]’ with ‘Char’
 Expected type: [String]
   Actual type: [[String]]

第一条似乎表明我无法摆脱 IO,而最后一条消息似乎表明,lines 将 return 列表的列表字符串,这对我来说也没有意义。

我怎样才能正确地做到这一点?

您声明 run[String] 值。但是 return 不是提供函数 return 值的关键字;它一个函数,类型为Monad m => a -> m areturn datadef 产生类型 IO [String] 的值,它成为函数的 return 值。

解决方案是为 run 提供正确的 return 类型:

run :: IO [String]
run = do
    ...

run 也可以更简洁地定义为

run = fmap lines (readFile "play.txt")

虽然 do 语法建议是,但无法从 IO 操作中提取值 out;您所能做的就是 "push" 调用 lines 进入 操作。