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