Is there a more succinct way to write code like this that has a lot of sharing between branches of the case statement?(This is the main part of my solution to one of the Round 1 problems of the Facebook Hacker Cup 2012. The round is over.)type Memoizable a = a -> arecoveries :: Int -> Memoizable (String -> Int)recoveries m = go  where go self ('0':_) = 0        go self [] = 1        go self ss = flip rem 0xfaceb00c $ case analysis ss of          HasMany            | cValid -> cCase + bCase + aCase            | bValid -> bCase + aCase            | aValid -> aCase          Has2            | bValid -> bCase + aCase            | aValid -> aCase          Has1            | aValid -> aCase          _            | otherwise -> 0          where a = digitToInt (first ss)                b = a * 10 + digitToInt (second ss)                c = b * 10 + digitToInt (third ss)                aValid = a <= m                bValid = b <= m                cValid = c <= m                aCase = self (drop 1 ss)                bCase = self (drop 2 ss)                cCase = self (drop 3 ss)-- not to be confused with functions of same name from Control.Arrowfirst (x:_) = xsecond (_:x:_) = xthird (_:_:x:_) = xdata Analysis = Empty | Has1 | Has2 | HasMany-- a dumb little function to help with safety and sharing                       analysis :: [a] -> Analysisanalysis [] = Emptyanalysis [_] = Has1analysis [_,_] = Has2analysis _ = HasMany
Safety, sharing, and laziness
haskell