[Haskell-cafe] Re: Diagnosing stack overflow

apfelmus apfelmus at quantentunnel.de
Fri Aug 17 04:24:34 EDT 2007


Justin Bailey wrote:
> -- Determines if the length of the strings in the list is longer than the given
> -- count. If not, amount the list falls short is returned. Otherwise,
> -- -1 indicates the prefix list is at least that long. If the count is zero and
> -- the list is empty or just null strings, -1 is also returned.
 >
> prefixesAtLeast :: Int -> [S.ByteString] -> Int

While that doesn't help your stack overflow problem, it's not very 
haskellish to return magic numbers. A Maybe type is more appropriate here.

> prefixesAtLeast !0 !ss
>   | null ss = 0
>   | all S.null ss = 0
>   | otherwise = -1
> prefixesAtLeast !n !ss = prefixesAtLeast' n ss
>   where
>       prefixesAtLeast' !n ss
>         | n < 0 = -1
>         | null ss = n
>         | otherwise =
>             let (!s : (!rest)) = ss
>             in
>               prefixesAtLeast' (n - (S.length s)) rest

Extracting the head and tail of  ss  with a let statement could lead to 
  a huge unevaluated expression like

   rest = tail (tail (tail (...)))

but the null test are likely to force it. Also note that the case  n = 0 
is quite rare. In any case, I'd write the function as

   lengthExcess :: Int -> [S.ByteString] -> Maybe Int
   lengthExcess n ss
      | n <= 0    = Nothing
      | otherwise = case ss of
         []     -> Just n
         (s:ss) -> lengthExcess (n - S.length s) ss

Note the that the function name is chosen to mnemonically match the 
result type Maybe Int, i.e. "the excess is Just 5 characters" or "the 
excess is Nothing".

Regards,
apfelmus



More information about the Haskell-Cafe mailing list