创建一个Haskell函数打印并返回一个值

创建一个Haskell函数打印并返回一个值

问题描述:

这里是我的功能:创建一个Haskell函数打印并返回一个值

foo :: Int -> Int 
foo i = do 
    putStrLn "Foo Function has run!" 
    return (i*2) 

上面有一个编译时错误。

我希望它是,如果我这样做的情况下:

bar = foo 6 

酒吧将12

但是当函数第一次运行,它打印出字符串“富功能跑!” 我该怎么做?

您必须将该功能变为IO动作。哈斯克尔严格执行你分开代码,不会从IO代码,不会:

foo :: Int -> IO Int 
foo i = do 
    putStrLn "Foo Function has run!" 
    return (i * 2) 

然后,您可以在另一个内部IO函数提取此值:

main :: IO() 
main = do 
    bar1 <- foo 6 
    bar2 <- foo bar1 
    print (bar1, bar2) 

为什么哈斯克尔选择这条路的原因有许多不同的,但一些重要的(没有特定的顺序)是:

  • 可测性。任何功能更容易测试,因为它始终只取决于其输入,而不是应用程序的状态
  • Equational reasoning。这意味着你可以推理你的代码,就好像它只是数学函数一样。您可以更轻松地对代码进行随机播放。
  • 编译器优化。如果编译器没有副作用,编译器可以自由选择何时以及如何调用函数,它可以将调用推迟到以后,并且可以在编译后的代码中执行速度更快的内部循环。
  • 可组合性。 Haskell类型系统非常丰富,并且以这种方式分离类型实际上允许您编写比在C#,Java或Python中能够实现的抽象更多的抽象。
  • 代码清晰度。如果你看到一个函数只是返回一个值而不是一个IO动作,你马上就会知道很多关于这个函数的知识。这种类型的签名是一种承诺,您不必担心该函数可能会破坏您的应用程序。另一方面,如果它确实返回IO动作,则表示您必须更加小心。
+0

这真是太神奇了,但如果我没有使用Int而是使用M.Map String Int。我试过“IO M.Map String Int”和“IO(M.Map String Int)”,但都产生错误 – 2014-11-14 22:34:33

+0

@YahyaUddin他们产生了什么错误?你在上面发布的第二个例子应该工作得很好。 'return'函数在它的参数和返回类型中是多态的,它可以和你给它的任何类型一起使用。 – bheklilr 2014-11-14 22:39:39

+0

我编辑后发布错误消息 – 2014-11-14 22:41:04