在 haskell 程序中有两种不同的使用方式IO,例如:
main :: IO ()
-- and
readLine :: IO Int
这两者有什么区别?
IO ()并且IO Int从根本上非常相似。 Int并且()都是 Haskell 中的两种类型。 ()仅在它只有一个值(也用 表示())的意义上是特殊的,所以我们从来没有真正对它感兴趣。
唯一的区别是它们的返回值。 main返回一个类型的值,()你的readLine返回一个Int. 也许这个例子会有所帮助:
main = do
x <- putStrLn "Test"
print x
当你运行它时,它会输出:
>>> main
Test
()
print 语句打印 a()因为那是 的返回值putStrLn:
putStrLn :: String -> IO ()
您通常不绑定类似返回值的原因是这样做不会putStrLn获得任何信息,因为()无论如何它总是返回。
IO Int意思是:这是一个 IO 动作,它return是一个 Int。
IO ()意思是:这是一个不返回任何有意义结果的 IO 操作。(如main。)
IO ()是可以执行以提取 type 值的操作的类型()。type 只有一个(非底部)值(),它也是拼写的()(您可以通过知道您是在查看类型表达式还是值表达式来区分它们,就像以大写字母开头的名称是类型构造函数一样或数据构造函数,具体取决于您查看的是类型表达式还是值表达式)。由于只有一个(非底部)值,因此该值绝对不会告诉您任何信息(严格来说,它至少告诉您计算确实成功终止,仅此而已)。所以IO ()通常用作我们只对它们的副作用感兴趣的 IO 操作类型。
putStrLn "Hello World"是类型值的示例IO ()。它根本不计算任何有趣的东西。将字符串写入终端产生的值是多少?获取()它的执行时间只会告诉我们它确实执行了。
IO Int是可以执行以提取 type 值的操作的类型Int。与所有 IO 动作一样,它究竟做了什么会对程序之外的世界产生影响和影响;Haskell 对他们一无所知。但它确实知道执行该操作将产生一个 Haskell 类型的值Int,不管它可能做什么。
readLn :: IO Int是类型值的一个示例IO Int(类型注释作为独立表达式是必要的,以避免歧义;在更广泛的上下文中,您实际使用从readLn某些Int特定操作中提取的值,您可能会不使用它)。与将字符串写入终端不同,从终端读取字符串并将其转换为 anInt 确实会产生一个值。
更普遍IO的是可以应用于任何类型的类型构造函数;IO a是可以执行的执行类型,并会产生 type 的值a。以上两者都只是其中的例子;两者都没有特别处理。()是一个完全普通的类型,并且()是该类型的一个完全普通的值,但是因为这些值不传达任何信息(除了“此计算成功终止”),您通常不会看到()它自己;它往往只与应用的类型构造函数一起使用,例如 in IO (),用于我们只关心类型构造函数添加的结构的值,而不关心它“内部”的值。