【问题标题】:Why is the output of this Haskell function an IO String instead of a String为什么这个 Haskell 函数的输出是 IO 字符串而不是字符串
【发布时间】:2020-01-10 17:17:01
【问题描述】:

我正在通过learnyouahaskell.com 学习 Haskell,并想在完成输入/输出模块之前测试一些概念。不过,尽管这看起来很简单,但我无法通过谷歌搜索或兜售我的方法。

当我尝试运行以下代码时

getName = do
  name <- getLine
  return name

getName 的输出变为IO String 类型的元素,而不是String,即使名称肯定是String

通过阅读文档和其他 StackVverflow 的问题,我无法弄清楚为什么当我将 getName 声明为函数时会发生这种情况(当我直接在 main 上使用绑定

【问题讨论】:

  • 因为return 的类型为Monad m =&gt; a -&gt; m a。您不能从IO 中“解包”一个值。您可以将IO 视为制作String 的“配方”,这与字符串不同。
  • 如果您有命令式语言的背景,请注意 Haskell 中的 return 与那些语言中的 return 非常不同。 return 是 Haskell 中的一个函数,在本例中是一个类型为 String -&gt; IO String 的函数。
  • 我明白了。非常感谢,伙计们。我完全忽略了return 在这种情况下的工作原理。
  • 如果你进一步阅读 LYAH,你会发现所有这些都得到了解释(在 Monads 的章节中)。 Haskell 中的 IO 和 do 表示法,当第一次遇到“这就是你在 Haskell 中执行 IO 的方式”时,总是看起来有点“神奇”,这些问题是非常自然的。正如我所说,他们稍后会得到答复。
  • 另外值得注意的是,do {x&lt;-foo; return x}monad laws 本身完全相同。所以你所有的代码真正要做的就是定义一个新名称getName = getLine

标签: string haskell io bind monads


【解决方案1】:

return 函数在概念上与 return 在 C++、Java 和 Python 等语言中的作用不同。 return :: Monad m =&gt; a -&gt; m a 接受 a(此处为 String),并生成 m a(此处为 IO a)。

do 符号是语法糖。如果我们将声明脱糖,您会写道:

getName = getLine >>= (\name -> return name)

或更清洁:

getName = getLine >>= return

因此,绑定函数(&gt;&gt;=) :: Monad m =&gt; m a -&gt; (a -&gt; m b) -&gt; m b 的第一个操作数是m a,第二个是函数a -&gt; m b,并产生一个m b。由于getLine :: IO StringIO String,这意味着mIO 相同,aString 相同。 return :: Monad m =&gt; a -&gt; m a,清楚地表明这里的ba 相同。

那么这里的IO 是什么。一个经常使用的比喻是recipe。在这个比喻中,IO a 是一组说明,当您遵循这些说明时,您将得到一个a。但这并不意味着该配方是a

(&gt;&gt;=) 这里基本上说,在左边我有一个制作a 的配方,在右边我有一个函数可以将a 转换为制作b 的配方,所以我们可以用这两个构造一个配方来制作b

人们经常问如何从IO a 中解开a,但从概念上讲它没有多大意义。您不能从制作蛋糕的食谱中“打开”蛋糕。您可以按照说明制作蛋糕。遵循说明是main 最终会做的事情。因此,我们可以构建一个主程序将执行的(长)配方。但是我们不能解开这些值。

严格来说,有一个函数unsafePerformIO :: IO a -&gt; a 可以做到这一点。但强烈建议不要使用它。 Haskell 中的函数应该是 pure 的,这意味着对于相同的输入,我们总是检索相同的输出。 getLine 本身是纯粹的,因为它总是产生相同的配方 (IO String)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多