<br><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">This is what I have so far:<br><br>&gt; type Pid = FilePath<br>&gt; type Uid = String
<br>&gt;<br>&gt; type PsData &nbsp; &nbsp; = Map String Uid<br>&gt; type PsChildren = Map Pid PsInfo<br>&gt;<br>&gt; data PsInfo = PsInfo PsData PsChildren<br>&gt; type PsMap &nbsp;= Map Pid PsInfo<br>&gt; type PsTree = Map Pid PsInfo<br>
&gt;<br>&gt; parent :: PsData -&gt; Pid<br>&gt; parent psData = fromJust $ Map.lookup &quot;PPid&quot; psData<br>&gt;<br>&gt; getProcInfo :: PsData -&gt; String -&gt; IO PsData<br>&gt; getProcInfo psData line = do<br>&gt; &nbsp; case matchRegex (mkRegex &quot;^([a-z]+):[[:space:]]+(.*)$&quot;) line of
<br>&gt; &nbsp; &nbsp; Nothing &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt; return (psData)<br>&gt; &nbsp; &nbsp; Just [key, value] -&gt; return (Map.insert key value psData)<br>&gt;<br>&gt; procInfo :: Pid -&gt; IO PsInfo<br>&gt; procInfo pid = do<br>&gt; &nbsp; procData &lt;- readFile $ &quot;/proc/&quot; ++ pid ++ &quot;/status&quot;
<br>&gt; &nbsp; psData &lt;- foldM getProcInfo Map.empty (lines procData)<br>&gt; &nbsp; let [rUid, eUid, _] = words $ fromJust (Map.lookup &quot;Uid&quot; psData)<br>&gt; &nbsp; let [rGid, eGid, _] = words $ fromJust (Map.lookup &quot;Gid&quot; psData)
<br>&gt; &nbsp; let uids = Map.fromList [(&quot;RUid&quot;, rUid), (&quot;EUid&quot;, eUid),<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(&quot;RGid&quot;, rGid), (&quot;EGid&quot;, eGid)]<br>&gt; &nbsp; let psData&#39; = Map.union psData uids
<br>&gt; &nbsp; return (PsInfo psData&#39; Map.empty)<br><br>I tried this for insertProc, but it obviously doesn&#39;t work... what would<br>be the correct way to do this?<br><br>&gt; insertProc :: Pid -&gt; StateT PsMap IO PsInfo
<br>&gt; insertProc pid = do<br>&gt; &nbsp; proc &lt;- procInfo pid -- XXX this is obviously wrong...<br>&gt; &nbsp; psMap &lt;- get<br>&gt; &nbsp; put (Map.insert pid proc psMap)<br>&gt; &nbsp; return (proc)<br><br>A second question: is it possible to make getProcInfo&#39;s type to be
<br>PsData -&gt; String -&gt; PsData and use some operation similar to lift so<br>that it can be used with foldM, instead of making its return type to be<br>IO PsData explicitely?<br></blockquote><br>Yes, and in fact, you don&#39;t even need foldM.&nbsp; 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.&nbsp; Something like this:
<br><br>&gt; procInfo :: Pid -&gt; IO PsInfo<br>&gt; procInfo pid = do<br>&gt; &nbsp; procData &lt;- readFile $ &quot;/proc/&quot; ++ pid ++ &quot;/status&quot;<br>&gt;&nbsp;&nbsp; return $ processData procData<br>&gt;<br>&gt; processData :: String -&gt; PsInfo
<br>&gt; ... and so on ...<br><br>and so on.&nbsp; Now instead of using foldM you can just use foldr.&nbsp; IO is a cancer, best to keep it confined to as little of your program as possible! =)<br><br>-Brent<br></div>