
On Mon, 2008-10-06 at 21:06 -0500, Mike Coleman wrote:
There's a readInt method, which I guess I could use, but it returns a Maybe, and I don't see how I can easily strip that off.
You can use Data.Maybe's 'mapMaybe' function "The mapMaybe function is a version of map which can throw out elements. In particular, the functional argument returns something of type Maybe b. If this is Nothing, no element is added on to the result list. If it just Just b, then b is included in the result list." So we change this:
-- lazy version (doesn't compile)
-- file: ch08/SumFile.hs
import qualified Data.ByteString.Lazy.Char8 as L
main = do contents <- L.getContents print (sumFile contents) where sumFile = sum . map read . L.words
To this: import qualified Data.ByteString.Lazy.Char8 as B import Data.Maybe (mapMaybe) main = do contents <- B.getContents print (sumFile contents) where sumFile = sum . map fst . mapMaybe B.readInt . B.words Now, there is a problem with this; the original version will not read integers that are followed by garbage, whereas this one will. The difference is between readInt and read: (read "2a") will fail, (readInt "2a") will return Just (2,"a") readInt is really designed with parsers in mind. So, we need to filter out anything readInt returns with a non-empty string in the right part of the tuple. Ending up with this: sumFile = sum . map fst . filter (B.null . snd) . mapMaybe B.readInt . B.words Actually, after saying this, the original version probably just dies when given garbage :P