在Haskell每个函数返回一个特定类型的值。
在这种情况下,doubleMe
函数返回Int
类型的值。当你从ghci解释器加载一个文件时,它会从文件中加载所有的函数,并使它们可用。
main
函数是一个稍微特殊的函数,非常类似于其他语言。它定义了一个Haskell程序的入口点。但是,由于它只是另一个Haskell函数,它也必须返回一个特定类型的值。 main
函数受限于返回IO
类型的值,最常见的是IO()
。
IO
本身也比较特殊,属于一类monads。您可以在IO
单子here.
读了现在让我们回到你的代码:
main = do
doubleMe 2
忽略do
语法一会儿。您基本上告诉编译器main
函数返回doubleMe 2
,它是Int
类型。这不会飞。 main
已将返回值IO
类型。在这种情况下,您可以使用return
函数将Int
值转换为IO Int
值。 (return
功能是所有单子的类型一定是很简单的把功能,将其转换任何类型的值,为一元值。)
所以这变为:
main = do
return (doubleMe 2)
这是完全合法的代码,并将编译。但是,一旦你运行该程序,你会注意到它没有做任何事情。这是因为该程序返回值4 事实上,你可以写它没有做的,它变成:
main = return (doubleMe 2)
这将工作过。
但让我们假设您想要打印出该值。这是IO
确实进来的地方。打印到屏幕上的操作是IO
。
main = do
print (doubleMe 2)
return (doubleMe 2)
甲do
表达式允许您链一组IO
动作。所以你的程序仍然会返回值4
,但它会首先评估表达式print (doubleMe 2)
。如预期的那样,实际上导致打印值doubleMe 2
。 检查ghci中的print
函数。
> :t print
print :: Show a => a -> IO()
打印功能适用于任何类型的,可以是所示的值和它导致IO
动作(打印到屏幕),但没有返回()
。
所有这些例子都可以工作,并且希望能让事情变得清晰一些。 (查看main
的类型签名)。
-- main :: IO Int
main = return (doubleMe 2)
-- main :: IO Int
main = do
print (doubleMe 2)
return (doubleMe 2)
-- main :: IO()
main = do
print (doubleMe 2)
return()
-- main :: IO()
main = do
print (doubleMe 2)
-- main :: IO()
main = print (doubleMe 2)
-- main :: IO()
main = do
print "Hello"
print (doubleMe 2)
return()
-- main :: IO String
main = do
print "Hello"
print (doubleMe 2)
return "Hello"
我建议使用ghci(交互式环境),所以你不必编译你的代码进行简单的手工测试。你可以只输入':l first.hs'来加载你的定义,然后输入'doubleMe 2',而不用每次都编辑 - 主要 - 我想要检查的东西。 (请参阅关于如何编写'main'的建议的答案。) – AndrewC
哇...非常感谢所有人如此迅速地回答我的问题。 Haskell社区对新手的友好态度令我印象深刻。每个人的意见都可以被接受为答案,但由于只能接受一个答案,所以我选择@ tanmaig's,因为他有最彻底的解释。再次感谢你们! – Sapience