0

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?

2
  • 1
    What about checking if there is a negative value in (a:as) before calling func2 x a:func x as? Commented May 2, 2011 at 6:42
  • Do you mean to stop the whole process of func whenever any element of any of the lists is negative? If so, what do you want func to return? The input list? Commented May 2, 2011 at 6:46

3 Answers 3

5

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 
Sign up to request clarification or add additional context in comments.

2 Comments

that's what I understood first, but I think he might want to stop func2 from being applied at all whenever one list contains a negative value...
Well the problem i have stems from the concept of unification. Where we look for rules to add and when we come across a rule like X -> f(x) we return a fail because the right hand side contains an x. now im not sure if you have seen unification before. so ill just be more specific on the problem at hand.
0

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.

6 Comments

func deals with lists of lists of Ints, not lists of ints.
yes, but i dont see the reason for downvote. he wrote a terminating base-case for negative inputs using a guard. after reading the question, thats what i consider to be the important characteristic of an answer. OP can adjust from there.
@jon_darkstar: see hammar's edited answer, I think that's more of what Kerry expected. But I must admit that the question is a bit unclear.
@Ptival: To downvote just because I was guessing is not very nice. But you know how karma works, I'll have an eye on the quality of your answers :-P
@Landei: Fair enough. (But for the record I decided to downvote because of the other problem, i.e. the mismatch of you answer to the question in terms of signature). Whatever... Be sure to haunt my every post, you'll have plenty of opportunities to avenge this! ^^ (and make the world better)
|
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.