
On Dec 5, 2007 10:44 AM, Jules Bean
Paulo J. Matos wrote:
Hello all,
Hi.
findAllPath :: (a -> Bool) -> (BTree a) -> Maybe [[a]] findAllPath pred (Leaf l) | pred l = Just [[l]] | otherwise = Nothing findAllPath pred (Branch lf r rt) | pred r = let lfpaths = findAllPath pred lf rtpaths = findAllPath pred rt in if isNothing lfpaths && isNothing rtpaths then Nothing else if isNothing lfpaths then Just (map (r:) $ fromJust rtpaths) else if isNothing rtpaths then Just (map (r:) $ fromJust lfpaths) else Just (map (r:) $ fromJust rtpaths ++ fromJust lfpaths) | otherwise = Nothing
Ignoring the fact that you found a better way to write this entirely, a style point.
Use of isNothing and fromJust and a cascade of ifs is generally a poor sign, much better to use case:
findAllPath pred (Branch lf r rt) | pred r = case (findAllPath pred lf,findAllPath pred rt) of (Nothing,Nothing) -> Nothing (Nothing,Just rtpaths) -> Just (map (r:) rtpaths) (Just lfpaths,Nothing) -> Just (map (r:) lfpaths) (Just lfpaths,Just rtpaths) -> Just (map (r:) $ rtpaths ++ lfpaths) | otherwise = Nothing
the general pattern is : replace isNothing with a case match on Nothing, replace fromJust with a case match on Just, don't be afraid to case two expressions at once.
Hope someone finds that useful,
Thanks, Although I think that the general thread diverged from my initial question, here it is again, why is this terrible function (I know it is ugly) evaluating all of the resulting list when I just request the head? (at seems from my experiments that's what it seems to be doing). BTW, I thought that the problem of " evaluating all of the resulting list when I just request the head " was related to argument strictness but from the other mails, I think I was wrong. :)
Jules
-- Paulo Jorge Matos - pocm at soton.ac.uk http://www.personal.soton.ac.uk/pocm PhD Student @ ECS University of Southampton, UK