Lovely!<br><br>Perhaps a stylistic shift would encourage writing this sort of elegant, fusion-friendly code.<br><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> -- Generalized version of "interact". Encapsulates data getter & putter.
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> genInteract :: IO i -> (o -> IO ()) -> ((i -> o) -> IO ())</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> genInteract get put = \ f -> get >>= put . f</span><br style="font-family: courier new,monospace;"><br>The intention here is that i and o are pure value types (no IO). Solutions 2 and three use the following specialization.
<br><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> -- Lazy ByteString in and showable out</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
lGetPrint :: Show o => (L.ByteString -> o) -> IO ()</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> lGetPrint = genInteract L.getContents print</span>
<br><br>Then rewrite solution 2 as follows:<br><span style="font-family: courier new,monospace;"></span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> main = lGetPrint f
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> where</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
f contents = foldl' (test k) 0 . map int . take n $ ls
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> where</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
(l:ls) = L.lines contents</span><span class="q"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> [n,k] = map int (L.split ' ' l)</span><br><br>
</span>And solution 3 similarly.
<br><br>Plug: for additional examples and a more general approach to separating out IO, my blog post "<a href="http://conal-elliott.blogspot.com/2007/02/separating-io-from-logic-example.html" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">
separating IO from logic -- example
</a>", which uses the <a href="http://www.haskell.org/haskellwiki/TV" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">TV</a> library.<br>