如何在Haskell中的递归函数中终止?

时间:2011-05-02 06:32:32

标签: haskell recursion termination

我有一个需要在某种条件下终止的功能。例如,我们说我们有以下功能:

func :: Int -> [[Int]] -> [[Int]]

func _ [] = []

func x (a:as) = func2 x a:func x as

func2 :: Int -> [Int] -> [Int]

func2 _ [] = []

func2 x (a:as) = x*a:func2 x as

假设我想要将func调用为正常,但每当我们在[[Int]]输入中得到负值时,我们就会终止。所以我们只处理正值。所以你怎么能让func2发送一些信号来退出整个过程而不是继续?

3 个答案:

答案 0 :(得分:5)

首先,您的功能可以更简单地编写为

func1 x = map (func2 x)
func2 x = map (*x)

现在,当遇到负值时,很容易将func2更改为停止:

func2 x = map (*x) . takeWhile (> 0)

修改

因此,如果我理解正确,那么如果遇到负值,则希望整个计算失败。一种方法是将结果包装在Maybe中。然后我们可以用monadic风格写这个:

func1 :: Int -> [[Int]] -> Maybe [[Int]]
func1 x = mapM (func2 x)

func2 :: Int -> [Int] -> Maybe [Int]
func2 x as = do
    guard $ all (>= 0) as
    return $ map (*x) as 

答案 1 :(得分:1)

我不太确定你的意思,但我会试一试:

func _ [] = []
func x (a:as) | a < 0 = []
              | otherwise = func2 x a:func x as

这将以与空列表相同的方式终止负值的计算。我希望这就是你想要的。

答案 2 :(得分:0)

如果你不介意两次遍历func2中的列表,这可能有效:

导入Data.Maybe

func :: Int - &gt; [[Int]] - &gt; [[INT]]
func a xss = map fromJust。 takeWhile就是。 map(func2 a)$ xss

func2 :: Int - &gt; [Int] - &gt;也许[Int]
func2 a xs
|任何(&lt; 0)xs = Nothing
|否则=只是。 map(* a)$ xs