首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >简单的haskell代码无法编译

简单的haskell代码无法编译
EN

Stack Overflow用户
提问于 2014-04-13 22:48:21
回答 5查看 962关注 0票数 0

我开始学习Haskell,只是尝试了一个简单的代码,当我运行时,它显示了一些错误。

代码语言:javascript
复制
doubleMe :: Int -> Int
doubleMe x = x + x

main = do
    doubleMe 2

ghc -c first.hs

这些错误是:

$ ghc -c first.hs first.hs:4:1:在检查函数‘IO t0' with actual type’的类型时,无法匹配表达式: main中预期的IO t0' with actual typeInt类型

当我使用GCHi进行调试时,没有问题先加载doubleMe函数,然后再调用它。任何帮助都将不胜感激。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2014-04-14 02:00:23

Haskell中的每个函数都返回一个特定类型的值。

在这种情况下,doubleMe函数返回一个Int类型的值。当您从ghci解释器加载一个文件时,它会从该文件加载所有函数,并使它们对您可用。

main函数是一个稍微特殊的函数,与其他语言非常相似。它定义了Haskell程序的入口点。但是,由于它只是另一个Haskell函数,所以它也必须返回一个特定类型的值。main函数被约束返回一个IO类型的值,最常见的是IO ()

IO本身也非常特殊,属于一种称为monad的类型。您可以在IO monad 这里。上阅读

现在让我们回到您的代码:

代码语言:javascript
复制
main = do
    doubleMe 2

暂时忽略do语法。您基本上是告诉编译器,main函数返回的是Int类型的doubleMe 2。这个飞不了。main必须返回一个IO类型的值。在这种情况下,可以使用return函数将Int值转换为IO Int值。(return函数是所有一元类型必须具有的函数。简单地说,它将任何类型的值转换为一元值。)

这就变成了:

代码语言:javascript
复制
main = do
    return (doubleMe 2)

这是完全有效的代码,并将编译。然而,一旦你运行了这个程序,你会发现它什么也不做。这是因为程序返回值4。实际上,您可以在没有do的情况下编写它,它变成:

代码语言:javascript
复制
main = return (doubleMe 2)

这个也能用。

但是,让我们假设,您希望打印出该值。这就是IO真正进入的地方。打印到屏幕上是一个IO动作。

代码语言:javascript
复制
main = do
          print (doubleMe 2)
          return (doubleMe 2)

do表达式允许您链接一组IO操作。因此,您的程序仍将返回值4,但它将首先计算表达式print (doubleMe 2)。正如预期的那样,这实际上会导致打印值doubleMe 2。检查ghci中的print函数。

代码语言:javascript
复制
> :t print
print :: Show a => a -> IO ()

print函数可以处理任何类型的值,并且它会导致IO操作(打印到屏幕上),但不返回任何()

所有这些例子都能起作用,希望能让事情变得更清楚。(查看main的类型签名)。

代码语言:javascript
复制
-- 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"
票数 8
EN

Stack Overflow用户

发布于 2014-04-13 23:54:58

main必须是IO a类型的值,而doubleMe 2具有Int类型。您可能希望print值:

代码语言:javascript
复制
main = print (doubleMe 2)
票数 6
EN

Stack Overflow用户

发布于 2014-04-13 22:55:41

它不起作用,因为任何使用do表示法的东西都必须返回一个monad。GHCI做了一些事情来使它更有用,但它的工作方式并不完全像GHC编译的代码。

print :: Show a => a -> IO ()

print接受一个作为Show实例的值,并返回一个空的IO操作。这很可能是你想做的事。

main = print (doubleMe 2)

应该能像你想做的那样发挥作用。您没有定义main函数的类型,但是在haskell中,必须有main :: IO ()类型。查看doubleMe的类型,您可能会发现代码不能工作的原因。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23049409

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档