i have a problem with one function which have initial value y and then list [x] function needs to sum y and all elements of list and if y drops below zero at start (if y is smaller than 0 at begining whithout any operations) during process or at the end of proces it returns True. i had comed up with this but it doesnt work. Thanks for help.
isOverdrawn :: Integer -> [Integer] -> Bool
isOverdrawn y [] = y < 0
isOverdrawn y (_:xs) = y isOverdrawn xs
isOverdrawn 100 [-99, -2, 1000] ~>* True
isOverdrawn 0 [0, 24, -42] ~>* True
isOverdrawn 0 [] ~>* False
CodePudding user response:
isOverdrawn :: (Num a, Ord a) => a -> [a] -> Bool
isOverdrawn y [] = y < 0
isOverdrawn y (x:xs) = y' < 0 || isOverdrawn y' xs where
y' = y x
There are a couple of problems with your code:
- At each step you want to check if
y
has gone sub zero, so you must do such a test. - You need to add each
x
toy
at each step but in the pattern(_:xs)
you are just ignoring individualx
es. - The function
isOverdrawn
takes 2 arguments but you are passing in only one in this caseisOverdrawn xs
.
CodePudding user response:
You can use the any
and scanl
functions for this. The any
function takes a list and a predicate on the list's element type, and returns whether the predicate is true on any of the list's elements. The scanl
function uses a given operation and starting value to combine all of a list's elements together, and returns a list of all of the intermediate values as well as the final answer. Combine them like this:
isOverdrawn :: (Ord a, Num a) => a -> [a] -> Bool
isOverdrawn y xs = any (< 0) (scanl ( ) y xs)