由于折叠,主要不编译

时间:2015-07-24 21:19:32

标签: haskell main

我已将此代码添加到f.hs文件中:

main = foldr (+) (0) [1,2,3]

当我使用时:

:l f.hs

我收到错误:

[1 of 1] Compiling Main             ( f.hs, interpreted )

f.hs:1:14:
    No instance for (Num (IO t0)) arising from a use of ‘+’
    In the first argument of ‘foldr’, namely ‘(+)’
    In the expression: foldr (+) (0) [1, 2, 3]
    In an equation for ‘main’: main = foldr (+) (0) [1, 2, 3]
Failed, modules loaded: none.

我想使用trace并查看fold的输出。

为什么这段代码没有编译?

3 个答案:

答案 0 :(得分:5)

main的类型为IO (),而foldr (+) (0) [1,2,3]的类型为Num a => a。 GHC尝试将这些组合但失败,因为Num未定义IO a。据推测,您想要打印结果。试试这个

main = print $ foldr (+) (0) [1,2,3]

然后,加载到GHCi后,您可以致电main获取6

答案 1 :(得分:3)

主要类型应与类型IO a统一。但foldr (+) (0) [1,2,3]的类型为Num a => a

您可以像这样修改您的程序:

-- Note print return a value of type IO ()
main :: IO ()
main = print $ foldr (+) 0 [1,2,3] 

答案 2 :(得分:0)

我可以重现并解决问题。我发现http://www.quora.com/Why-cant-functions-be-defined-on-the-GHCi-repl给了我提示: 似乎REPL是" IO monad中的阻止。"如其他答案中所述。 符号可以用来表达一系列一个接一个地执行的monadic表达式。作为it can be seen at Wikibooks,它可以转换为monad bind操作链。

因此,您有两种选择:

一个是让main拥有签名main :: IO (),以便

main :: IO ()
main = print $ foldr (+) (0) [1,2,3]

evaluateTwice :: IO()
evaluateTwice = do 
              main
              main
-- equvalent alternative as monadic bind operations, see Wikibooks
evaluateTwice = main >>= \ x1 -> main

将两个调用链接到main monad的IO(使用bind),返回IO monad的新实例。这是其他海报基本上建议的。

或者,您可以使用let

let main = foldr (+) (0) [1,2,3]

定义了一个"变量"。