Haskell,如何在函数中打印值和返回

tes*_*der 4 iteration haskell

我尝试编写自定义函数,它采用数组并迭代它,我需要打印每个数字并递归启动相同的函数,但我得到错误

输入`main'解析错误

码:

firstitem n = if n /= [] n firstitem( tail n )


main = do
    print(firstitem [1,2,3])
Run Code Online (Sandbox Code Playgroud)

Chr*_*lor 11

您的第一个问题是if语句的语法错误.你应该写

firstItem n = if {- condition-}
    then {- do this -}
    else {- do that -}
Run Code Online (Sandbox Code Playgroud)

其次,不清楚该功能firstItem应该做什么.听起来它应该返回列表的第一项,但是你的描述看起来好像你想迭代列表的所有元素.

您可以将迭代和打印组合成一个单独的函数,如下所示:

printAll xs = if null xs        -- If the list is empty
    then return ()              -- then we're done, so we quit.
    else do print (head xs)     -- Otherwise, print the first element
            printAll (tail xs)  -- then print all the other elements.

main = printAll [1,2,3]
Run Code Online (Sandbox Code Playgroud)

该函数null返回True如果列表为空,否则返回False.声明return ()你能想到的话说"有什么更多的过程,所以现在停止功能和返回任何结果".第三行和第四行包含"do block".do块基本上是一些粘合剂,它将两个动作绑定在一起print (head xs)printAll (tail xs)组合成一个动作.你可以用花括号写它,使它更清晰:

do {
  print (head xs);
  printAll (tail xs)
}
Run Code Online (Sandbox Code Playgroud)

虽然你实际上并不需要它们 - 缩进指定了你的意思.

这解决了你的问题,但它有点笨重.毕竟,Haskell应该是一种美妙的语言 - 所以让你的代码变得美丽!最好使用模式匹配将列表分成头部和尾部:

printAll []     = return ()
printAll (x:xs) = do print x
                     printAll xs
Run Code Online (Sandbox Code Playgroud)

那好多了.但它可能更模块化.嘿,也许我们可以创建一个将动作作为输入的泛型函数,并对列表的每个元素执行该操作:

repeatedly f []     = return ()
repeatedly f (x:xs) = do f x
                         repeatedly f xs

printAll xs = repeatedly print xs
Run Code Online (Sandbox Code Playgroud)

那很整齐.但实际上,已经有一个功能可以做到这一点.它被称为mapM_(有一个很好的理由,它被称为这个,但我现在不会进入它)并且它在Control.Monad模块中:

import Control.Monad

printAll xs = mapM_ print xs
Run Code Online (Sandbox Code Playgroud)

实际上,你可以放弃xs参数,编译器可以推断它应该在那里:

printAll = mapM_ print
Run Code Online (Sandbox Code Playgroud)

最后,你的代码很漂亮.希望有点帮助.