创建打印并返回值的haskell函数

Yah*_*din 2 haskell

这是我的功能:

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

以上有编译时错误.

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

bar = foo 6
Run Code Online (Sandbox Code Playgroud)

酒吧将是12.

但是当首次运行该函数时,它会输出字符串"Foo Function has run!" 我怎样才能做到这一点?

bhe*_*ilr 8

您必须将该功能转换为IO操作.Haskell严格强制您将执行IO的代码与不执行IO的代码分开:

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

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

main :: IO ()
main = do
    bar1 <- foo 6
    bar2 <- foo bar1
    print (bar1, bar2)
Run Code Online (Sandbox Code Playgroud)

Haskell选择这条路线的原因有很多种,但一些重要的(没有特别的顺序)是:

  • 可测性.任何函数都更容易测试,因为它总是只依赖于它的输入,而不是取决于应用程序的状态
  • 均等推理.这意味着您可以将您的代码推理为好像只是花哨的数学函数.您可以更轻松地对代码进行随机播放.
  • 编译器优化.编译器可以自由选择何时以及如何调用函数,如果它没有副作用,它可以将调用推迟到以后,并且它可以在运行得更快的编译代码中进行非常紧密的内部循环.
  • 组合性.Haskell类型系统非常丰富,以这种方式隔离类型实际上允许您编写比C#,Java或Python更多的抽象.
  • 代码清晰度.如果你看到一个函数只返回一个值而不是一个IO动作,你会立即对该函数有很多了解.该类型签名是一种承诺,您不必担心该函数可能会破坏您的应用程序.另一方面,如果它确实返回IO动作,则表示您必须更加小心.