Skip to content

Instantly share code, notes, and snippets.

@simg
Created August 3, 2019 10:48
Show Gist options
  • Save simg/97a83a9a355ea9aef464c54f9c52dc0b to your computer and use it in GitHub Desktop.
Save simg/97a83a9a355ea9aef464c54f9c52dc0b to your computer and use it in GitHub Desktop.
StateT Question
{-
This program parses a zip file and for each entry in the zip generates two lists of strings.
The lists of strings contain many values, some of which would be the same and some will be different.
I would like to count the number of instances of each string in both lists.
eg ["a1", "b1", "aa1", "aa1, "a1"] -> ["a1" -> 2, "b1" -> 1, "aa1" -> 2 ]
The zip contains very many small files.
I suspect I need to use a StateT monad transformer here but other than that I'm struggling.
Currerently the current code fails to compile with:
No instance for (Control.Monad.State.Class.MonadState a0 Codec.Archive.Zip.ZipArchive)
arising from a use of ‘get’
• In a stmt of a 'do' block: s <- get
Any suggestions appreciated
-}
parseZip :: FilePath -> IO Summary
parseZip infile outfile = do
flip runStateT (Summary empty empty) $ do
withArchive infile $ do
zipEntries <- keys <$> getEntries
mapM_ (\(i, entry) -> do
content <- getEntry entry
let (list1, list2) = parseEntry content
s <- get
put $ addSummaries s list1 list2
liftIO $ do
putStr $ show list1
putStr $ show list2
putStr "\n\n"
) $ zipEntries
return summary
data Summary = Summary {
list1 :: Map Text Int
, list2 :: Map Text Int
}
addSummaries :: Summary -> [Text] -> [Text] -> Summary
addSummaries s list1 list2 = undefined
summarise :: StateT Summary IO Summary -- do I even need this?
summarise = undefined
parseEntry :: ByteString -> ([Text], [Text])
parseEntry entry = undefined
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment