[Haskell-cafe] Is StateT what I need?
Brent Yorgey
byorgey at gmail.com
Mon Dec 17 15:41:48 EST 2007
> This is what I have so far:
>
> > type Pid = FilePath
> > type Uid = String
> >
> > type PsData = Map String Uid
> > type PsChildren = Map Pid PsInfo
> >
> > data PsInfo = PsInfo PsData PsChildren
> > type PsMap = Map Pid PsInfo
> > type PsTree = Map Pid PsInfo
> >
> > parent :: PsData -> Pid
> > parent psData = fromJust $ Map.lookup "PPid" psData
> >
> > getProcInfo :: PsData -> String -> IO PsData
> > getProcInfo psData line = do
> > case matchRegex (mkRegex "^([a-z]+):[[:space:]]+(.*)$") line of
> > Nothing -> return (psData)
> > Just [key, value] -> return (Map.insert key value psData)
> >
> > procInfo :: Pid -> IO PsInfo
> > procInfo pid = do
> > procData <- readFile $ "/proc/" ++ pid ++ "/status"
> > psData <- foldM getProcInfo Map.empty (lines procData)
> > let [rUid, eUid, _] = words $ fromJust (Map.lookup "Uid" psData)
> > let [rGid, eGid, _] = words $ fromJust (Map.lookup "Gid" psData)
> > let uids = Map.fromList [("RUid", rUid), ("EUid", eUid),
> > ("RGid", rGid), ("EGid", eGid)]
> > let psData' = Map.union psData uids
> > return (PsInfo psData' Map.empty)
>
> I tried this for insertProc, but it obviously doesn't work... what would
> be the correct way to do this?
>
> > insertProc :: Pid -> StateT PsMap IO PsInfo
> > insertProc pid = do
> > proc <- procInfo pid -- XXX this is obviously wrong...
> > psMap <- get
> > put (Map.insert pid proc psMap)
> > return (proc)
>
> A second question: is it possible to make getProcInfo's type to be
> PsData -> String -> PsData and use some operation similar to lift so
> that it can be used with foldM, instead of making its return type to be
> IO PsData explicitely?
>
Yes, and in fact, you don't even need foldM. The only thing that actually
uses IO is the readFile, so ideally you should just have a small function
that just does the readFile and then processes the result using some (pure)
functions. Something like this:
> procInfo :: Pid -> IO PsInfo
> procInfo pid = do
> procData <- readFile $ "/proc/" ++ pid ++ "/status"
> return $ processData procData
>
> processData :: String -> PsInfo
> ... and so on ...
and so on. Now instead of using foldM you can just use foldr. IO is a
cancer, best to keep it confined to as little of your program as possible!
=)
-Brent
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20071217/2c3e6963/attachment.htm
More information about the Haskell-Cafe
mailing list