[Haskell-cafe] Why is this strict in its arguments?

Jules Bean jules at jellybean.co.uk
Wed Dec 5 05:44:04 EST 2007


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,

Jules


More information about the Haskell-Cafe mailing list