简体   繁体   中英

How to terminate in a recursive function in Haskell?

I have a function that needs to terminate on a certain condition. So for example say we have the following functions:

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

Lets say that I want func one to be called as normal but whenever we get a negative value in the [[Int]] input, we terminate. so we only deal with positive values. so How could you make func2 send some signal to quit the whole process rather than continuing?

First of all, your functions can be written more simply as

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

Now it is easy to change func2 to stop when a negative value is encountered:

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

EDIT:

So if I understand this right, you want the entire computation to fail if a negative value is encountered. One way to do this is to wrap the result in a Maybe . We can then write this in a monadic style:

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 

I'm not really sure what you mean, but I'll give it a shot:

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

This terminates the calculation for a negative value in the same way an empty list would do. I hope this is what you want.

If you don't mind traversing the lists in func2 twice, this might work:

import Data.Maybe

func:: Int -> [[Int]] -> [[Int]]
func a xss = map fromJust. takeWhile isJust. map (func2 a) $ xss

func2:: Int -> [Int] -> Maybe [Int]
func2 a xs
| any (< 0) xs = Nothing
| otherwise = Just. map (*a) $ xs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM