Reputation: 1
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?
Upvotes: 0
Views: 7622
Reputation: 1
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
Upvotes: 0
Reputation: 139890
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
Upvotes: 5
Reputation: 54584
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.
Upvotes: 0