由于文件夹原因,主程序未编译



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

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

当我使用:

:l f.hs

I receive error:

[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的输出。

为什么这个代码不能编译?

mainIO ()类型,foldr (+) (0) [1,2,3]Num a => a类型。GHC试图将这些结合起来,但失败了,因为Num没有在IO a上定义。您可能希望打印结果。试试这个

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

然后,一旦你加载到GHCi,你可以调用main来获得6

main的类型应与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] 

我可以重现并解决这个问题。我找到了http://www.quora.com/Why-cant-functions-be-defined-on-the-GHCi-repl,它给了我提示:就像其他答案中所说的那样,REPL似乎是"IO单子中的do块"。do表示法可用于表示一系列依次执行的一元表达式。在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

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

也可以使用let

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

定义了一个变量

相关内容

  • 没有找到相关文章

最新更新