I want to write a function that checks if two lists are "almost" equal. The first parameter d
is used for precision - the difference between the elements must not exceed d
.
For example, nearlyEqual 0.5 [2,5] [2.5, 5.1]
equals True
, but nearlyEqual 0.1 [2,5] [2.5, 5.1]
equals False
.
I wrote this but it is not working:
nearlyEqual :: Int -> [Int] -> [Int] -> Bool
nearlyEqual d xs ys = foldr(&&) True $ zipWith (\x y -> abs(x-y)<=e)
What am I missing? Any help would be greatly appreciated!
CodePudding user response:
Not sure if it's a typo, but you're not passing xs
and ys
to your function.
nearlyEqual d xs ys = foldr(&&) True $ zipWith (\x y -> abs(x-y)<=e)
should be
nearlyEqual d xs ys = foldr(&&) True $ zipWith (\x y -> abs(x-y)<=e) xs ys
at least for it to typecheck.
A clearer implementation would make use of all
, which is of type Foldable t => (a -> Bool) -> t a -> Bool
, and of the function composition operator (.)
:
nearlyEqual d xs ys = all ((<= d) . abs) $ zipWith (-) xs ys
where zipWith (-) xs ys
is element-wise difference of the two lists, and all
verifies that the predicate (<= d) . abs
holds for all of the elements of that list; the predicate, given an argument, applies abs
to it, and then (<= d)
to the result.