<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<TITLE>Message</TITLE>

<META content="MSHTML 6.00.2900.2604" name=GENERATOR></HEAD>
<BODY>
<DIV><SPAN class=469025019-11032005><FONT face=Arial 
size=2>All,</FONT></SPAN></DIV>
<DIV><SPAN class=469025019-11032005><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; 
I'm having substantial difficulty understanding Jeff Newbern's Example 7.&nbsp; 
Would love some help.</FONT></SPAN></DIV>
<DIV><SPAN class=469025019-11032005>&nbsp;&nbsp;&nbsp; <FONT face=Arial 
size=2>My questions are: How does liftM2 know to lift fn into the _List_ monad? 
(Because it's the only possibility?)&nbsp; After fn is lifted, where is "bind" 
used in allCombinations?</FONT></SPAN></DIV>
<DIV><SPAN class=469025019-11032005><FONT face=Arial 
size=2></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=469025019-11032005>&nbsp;&nbsp;&nbsp; <FONT face=Arial 
size=2>Basically, I'd some a detailed explanation of how allCombinations works, 
cause I'm not grokking it...</FONT></SPAN></DIV>
<DIV><SPAN class=469025019-11032005>
<DIV><SPAN class=469025019-11032005><FONT face=Arial 
size=2></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=469025019-11032005><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; - 
Alson</FONT></SPAN></DIV></SPAN><SPAN class=469025019-11032005></DIV>
<DIV><PRE><SPAN class=469025019-11032005>---</SPAN></PRE><PRE><SPAN class=469025019-11032005></SPAN>import Monad

-- allCombinations returns a list containing the result of
-- folding the binary operator through all combinations
-- of elements of the given lists
-- For example, allCombinations (+) [[0,1],[1,2,3]] would be
--   [0+1,0+2,0+3,1+1,1+2,1+3], or [1,2,3,2,3,4]
-- and allCombinations (*) [[0,1],[1,2],[3,5]] would be
--   [0*1*3,0*1*5,0*2*3,0*2*5,1*1*3,1*1*5,1*2*3,1*2*5], or [0,0,0,0,3,5,6,10]
allCombinations :: (a -&gt; a -&gt; a) -&gt; [[a]] -&gt; [a]
allCombinations fn []     = []
allCombinations fn (l:ls) = foldl (liftM2 fn) l ls

-- print an example
showExample :: (Show a) =&gt; String -&gt; (a -&gt; a -&gt; a) -&gt; [[a]] -&gt; IO ()
showExample opName op ls = do putStrLn $ "opName over " ++ (show ls) ++ " = "
                              putStrLn $ "  " ++ (show (allCombinations op ls)) 

-- shows a few examples of using allCombinations
main :: IO ()
main = do showExample "+" (+)   [[0,1],[1,2,3]]
          showExample "*" (*)   [[0,1],[1,2],[3,5]]
          showExample "/" div   [[100, 45, 365], [3, 5], [2, 4], [2]]</PRE></SPAN></DIV>
<DIV><SPAN class=469025019-11032005><FONT face=Arial 
size=2></FONT></SPAN>&nbsp;</DIV></BODY></HTML>