繁体   English   中英

为什么此Haskell函数的输出是IO字符串而不是字符串

[英]Why is the output of this Haskell function an IO String instead of a String

我正在通过learningyouahaskell.com学习Haskell,并想在完成输入/输出模块之前测试一些概念。 尽管看起来很简单,但我仍无法用谷歌或笨拙的方式解决这个问题。

当我尝试运行以下代码时

getName = do
  name <- getLine
  return name

即使name绝对是StringgetName的输出也将成为IO String类型而不是String类型的元素

通过阅读文档和其他StackVverflow的问题,当我将getName声明为函数时(当我直接在main上直接使用bind <-操作时,就没有问题了),我无法弄清楚为什么会发生这种情况。

return 函数在概念上与C ++,Java和Python等语言中的return 函数并不相同。 return :: Monad m => a -> ma接受a (这里是String ),并产生ma (这里IO a )。

do记号是syntacticual糖。 如果我们对声明不加糖,那么您写道:

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

或更清洁的:

getName = getLine >>= return

因此,绑定函数(>>=) :: Monad m => ma -> (a -> mb) -> mb具有第一个操作数ma和第二个功能a -> mb并产生mb 由于getLine :: IO StringIO String ,因此这意味着mIO相同,而aString相同。 return :: Monad m => a -> ma ,清楚地表明ba相同。

那么这里的IO是什么。 一个经常使用的隐喻就是食谱之一 在此隐喻中, IO a是一组指令,当您遵循这些指令时,将获得a 但这并不意味着该食谱是a

(>>=)这里基本上是说,左手边有一个制作a的配方,右手边有个将a转换成要制作b的配方的函数,因此我们可以构造一个要点b的配方与这两个。

人们经常会问如何解开一个a出的IO a ,但在概念上它使没有太大意义。 您不能从食谱中“解包”蛋糕来制作蛋糕。 您可以按照说明做蛋糕。 遵循指示是main最终操作。 因此,我们可以构造一个主要的(长)配方。 但是我们不能解开价值观。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM