【问题标题】:How to convert data from IO(String) to String in haskell [duplicate]如何在haskell中将数据从IO(String)转换为String [重复]
【发布时间】:2011-12-30 19:46:50
【问题描述】:

可能重复:
A Haskell function of type: IO String-> String

我正在使用 Haskell 中的 readFile 函数从文件中读取一些数据。但是这个函数会返回一些存储为IO String 的数据。有谁知道如何将这些数据转换为 String 类型(或任何从文件中读取 String 的函数,没有 IO () 类型)?

【问题讨论】:

  • 虽然这绝对是重复的,但我不得不怀疑.. 是什么让人们认为有这样一个函数,它使执行 IO 以获取字符串而不是执行 IO 的操作?
  • 这是对副作用的普遍误解。
  • 我认为它与副作用的关系比几乎每个人在理解它们之前都使用 monad 的作用要小。

标签: haskell functional-programming io monads


【解决方案1】:

这是一个关于从一元值中提取数据的非常普遍的问题。

大体思路是使用>>=函数:

main = readFile foo >>= \s -> print s

>>= 接受 2 个参数。它从第一个参数中提取值并将其传递给第二个参数。第一个参数是单子值,在本例中为 IO String,第二个参数是一个接受普通非单子值的函数,在本例中为 String

这个模式有一个特殊的语法:

main = do
   s <- readFile foo
   print s

但意思同上。 do 表示法对初学者和某些复杂情况更方便,但显式应用 &gt;&gt;= 会导致代码更短。例如,这段代码可以写成只是

main = readFile foo >>= print

还有一大类库函数可以在单子和非单子值之间进行转换。其中最重要的是returnfmapliftM2&gt;=&gt;

monad 的概念除了以引用透明的方式表示 IO 之外非常有用:这些帮助器对于错误处理、处理隐式状态和 monad 的其他应用程序非常有用。

第二重要的单子是Maybe

【讨论】:

  • most of the time the explicit application of &gt;&gt;= leads to a better code - 我想知道您如何证实这一说法。尽管如此,+1 以获得良好的解释。
  • “大部分时间”和“更好”是停用词。感谢您发现它们。固定。
【解决方案2】:

在这种情况下,我会将 IO 类型视为 functor,而不是从中获取值,而是将我的函数发送到其中并让 Functor 实例处理创建新 IO包含我的函数结果的容器。

> :m +Data.Functor
> length <$> readFile "file.txt"
525

&lt;$&gt;fmap 的别名。我更喜欢&lt;$&gt;,但这只是个人喜好。

【讨论】:

  • 这不是一个错误的答案,但是当有人开始尝试理解一元值的概念时,你不能抛出 Applicative Functors让他们更加困惑。
  • @RomanGonzalez 是的,但我不确定他能否很好地掌握这一点而不会一开始就感到困惑。我也不想写课程。至少在这里/现在不是。小修正,我使用的只是一个函子,而不是一个应用函子。模块名称确实具有误导性。也许我应该使用Data.Functor...哦,我认为应该在Monad 之前考虑Functor。这更有意义。
猜你喜欢
  • 1970-01-01
  • 2011-07-11
  • 2023-01-28
  • 1970-01-01
  • 2015-07-20
  • 2012-05-01
  • 1970-01-01
  • 2011-05-23
  • 1970-01-01
相关资源
最近更新 更多