使用递归的 Haskell 循环

FAR*_*NIA 0 haskell

Haskell 和函数式编程是我不熟悉的东西,这学期我第一次见到 Haskell。当我尝试进行递归时,我得到了无限循环(不是很自豪)

这是代码

import Data.List
import System.IO

mrLoop :: Int -> Int -> IO()
mrLoop a b = do
    if b == 10 then return ()
    else
        print(a*b)
    mrLoop a (b+1)


main = do mrLoop 2 0
Run Code Online (Sandbox Code Playgroud)

所以我试着玩它,不知何故它起作用了

mrLoop :: Int -> Int -> IO()
mrLoop a 10 = return()
mrLoop a b = do
    print(a*b)
    mrLoop a (b+1)
Run Code Online (Sandbox Code Playgroud)

但是我的一个朋友说这不是 Haskell 的方式。那么我如何以 Haskell 的方式做到这一点呢?为什么第一个代码不起作用?

Mar*_*ann 5

第一个版本永远递归,因为mrLoop a (b+1)动作在表达式之外if/else

换句话说,它要么什么都不做,要么打印a*b,然后无条件地递归到mrLoop a (b+1)。它会一直循环下去。

在后者的例子中,递归当图案匹配函数击中基情况下停止b10

您的朋友可能表示这不是 Haskell 方式,因为 Haskell 方式是将纯函数与不纯操作分开。

尝试是否可以将递归“循环”编写为纯函数(即没有IO)。它会返回什么?那么您如何使用该返回值来打印一系列结果呢?

  • 可能值得明确指出的是,“return”*不会*导致函数调用退出,这是 Haskell 初学者的常见误解。 (6认同)