<table cellspacing="0" cellpadding="0" border="0" ><tr><td valign="top" style="font: inherit;">All I meant was a small change:<br>&gt; makeVerifier :: (Int -&gt; Int -&gt; Int) -&gt; Int -&gt; (Int -&gt; Bool)<br>&gt; makeVerifier f m = divides m . foldl (+) 0 . zipWith f [1 .. ] . digits<br><br>which make some things simpler:<br><br>&gt; let checkIsbn = makeVerifier (*) 11&nbsp;&nbsp; &lt;== I liked this syntax better too, and it's what I had<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; originally.<br><br><br>BTW, here's a sneaky way do define digits:<br>&gt; digits :: Int -&gt; [Int]<br>&gt; digits = map digitToInt . show&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;== I haven't gotten to "show" yet. When needed? When not?<br><br>So then
 you'd have:<br><br>&gt; makeVerifier :: (Int -&gt; Int -&gt; Int) -&gt; Int -&gt; Int -&gt; Bool<br>&gt; makeVerifier f m = (== 0) . (`mod` m) . sum . zipWith f [1 .. ] . map digitToInt . show<br><br>Which looks pretty nice, I think.<br><br>&nbsp; -- Lennart<br><br>========<br><br>Very good. I've yet to replace the 'foldl' with 'sum', but will. Eliminating the 'divides' function is also a nice touch. With Haskell it seems there's always a way to make one's code ever briefer, and using built-ins is probably much faster than anything I'd cook up, but it takes time to learn these short-cuts.<br><br>Thanks for your comments.<br><br>Michael<br><br><br>--- On <b>Mon, 4/13/09, Lennart Augustsson <i>&lt;lennart@augustsson.net&gt;</i></b> wrote:<br><blockquote style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px;"><br>From: Lennart Augustsson &lt;lennart@augustsson.net&gt;<br>Subject: Re: [Haskell-cafe] Functions that return
 functions<br>To: "michael rice" &lt;nowgate@yahoo.com&gt;<br>Cc: haskell-cafe@haskell.org<br>Date: Monday, April 13, 2009, 10:33 AM<br><br><div class="plainMail">All I meant was a small change:<br>&gt; makeVerifier :: (Int -&gt; Int -&gt; Int) -&gt; Int -&gt; (Int -&gt; Bool)<br>&gt; makeVerifier f m = divides m . foldl (+) 0 . zipWith f [1 .. ] . digits<br><br>which make some things simpler:<br><br>&gt; let checkIsbn = makeVerifier (*) 11<br><br>BTW, here's a sneaky way do define digits:<br>&gt; digits :: Int -&gt; [Int]<br>&gt; digits = map digitToInt . show<br><br>So then you'd have:<br><br>&gt; makeVerifier :: (Int -&gt; Int -&gt; Int) -&gt; Int -&gt; Int -&gt; Bool<br>&gt; makeVerifier f m = (== 0) . (`mod` m) . sum . zipWith f [1 .. ] . map digitToInt . show<br><br>Which looks pretty nice, I think.<br><br>&nbsp; -- Lennart<br><br>On Mon, Apr 13, 2009 at 1:09 AM, michael rice &lt;<a ymailto="mailto:nowgate@yahoo.com"
 href="/mc/compose?to=nowgate@yahoo.com">nowgate@yahoo.com</a>&gt; wrote:<br>&gt; Example please.<br>&gt;<br>&gt; Michael<br>&gt;<br>&gt; --- On Sun, 4/12/09, Lennart Augustsson &lt;<a ymailto="mailto:lennart@augustsson.net" href="/mc/compose?to=lennart@augustsson.net">lennart@augustsson.net</a>&gt; wrote:<br>&gt;<br>&gt; From: Lennart Augustsson &lt;<a ymailto="mailto:lennart@augustsson.net" href="/mc/compose?to=lennart@augustsson.net">lennart@augustsson.net</a>&gt;<br>&gt; Subject: Re: [Haskell-cafe] Functions that return functions<br>&gt; To: "michael rice" &lt;<a ymailto="mailto:nowgate@yahoo.com" href="/mc/compose?to=nowgate@yahoo.com">nowgate@yahoo.com</a>&gt;<br>&gt; Cc: <a ymailto="mailto:haskell-cafe@haskell.org" href="/mc/compose?to=haskell-cafe@haskell.org">haskell-cafe@haskell.org</a>, "Daniel Fischer" &lt;<a ymailto="mailto:daniel.is.fischer@web.de" href="/mc/compose?to=daniel.is.fischer@web.de">daniel.is.fischer@web.de</a>&gt;<br>&gt; Date:
 Sunday, April 12, 2009, 6:59 PM<br>&gt;<br>&gt; You should use an curried function as f instead of a uncurried one.<br>&gt; Uncurried functions are rarely used in Haskell.<br>&gt;<br>&gt; &nbsp; -- Lennart<br>&gt;<br>&gt; On Sun, Apr 12, 2009 at 10:09 PM, michael rice &lt;<a ymailto="mailto:nowgate@yahoo.com" href="/mc/compose?to=nowgate@yahoo.com">nowgate@yahoo.com</a>&gt; wrote:<br>&gt;&gt; Thanks, guys!<br>&gt;&gt;<br>&gt;&gt; Boy, this bunch of complemented partially applied functions gives a whole<br>&gt;&gt; new meaning to the term "thinking ahead." And the whole shebang is waiting<br>&gt;&gt; on that input integer to set everything in motion. Pretty clever.<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt; To generalize, I changed the function to:<br>&gt;&gt;<br>&gt;&gt; makeVerifier :: ((Int,Int) -&gt; Int) -&gt; Int -&gt; (Int -&gt; Bool)<br>&gt;&gt; makeVerifier f m = divides m . foldl (+) 0 . map f . zip [1 .. ] . digits<br>&gt;&gt;<br>&gt;&gt; so, in
 Haskell<br>&gt;&gt;<br>&gt;&gt; let checkIsbn = makeVerifier (\ (i,d) -&gt; i * d) 11<br>&gt;&gt;<br>&gt;&gt; let checkUpc = makeVerifier (\ (i,d) -&gt; if odd i then d else 3*d) 10<br>&gt;&gt;<br>&gt;&gt; let checkCc = makeVerifier (\ (i,d) -&gt; if odd i then d else if d &lt; 5 then<br>&gt;&gt; 2*d else 2*d+1) 10<br>&gt;&gt;<br>&gt;&gt; let checkUsps = makeVerifier (\ (i,d) -&gt; if i == 1 then -d else d) 9<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt; I think I'm catching on.<br>&gt;&gt;<br>&gt;&gt; Michael<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt; --- On Sun, 4/12/09, Daniel Fischer &lt;<a ymailto="mailto:daniel.is.fischer@web.de" href="/mc/compose?to=daniel.is.fischer@web.de">daniel.is.fischer@web.de</a>&gt; wrote:<br>&gt;&gt;<br>&gt;&gt; From: Daniel Fischer &lt;<a ymailto="mailto:daniel.is.fischer@web.de" href="/mc/compose?to=daniel.is.fischer@web.de">daniel.is.fischer@web.de</a>&gt;<br>&gt;&gt; Subject: Re: [Haskell-cafe] Functions that return
 functions<br>&gt;&gt; To: <a ymailto="mailto:haskell-cafe@haskell.org" href="/mc/compose?to=haskell-cafe@haskell.org">haskell-cafe@haskell.org</a><br>&gt;&gt; Cc: "michael rice" &lt;<a ymailto="mailto:nowgate@yahoo.com" href="/mc/compose?to=nowgate@yahoo.com">nowgate@yahoo.com</a>&gt;<br>&gt;&gt; Date: Sunday, April 12, 2009, 12:15 PM<br>&gt;&gt;<br>&gt;&gt; Am Sonntag 12 April 2009 17:38:53 schrieb michael rice:<br>&gt;&gt;&gt; The following are exercises 5.10, and 5.11 from the Scheme text "Concrete<br>&gt;&gt;&gt; Abstractions" by Max Hailperin, et al. The text at that point is about<br>&gt;&gt;&gt; writing verifiers to check ID numbers such as ISBNs, credit card numbers,<br>&gt;&gt;&gt; UPCs, etc.<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; ======<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; Exercise 5.10<br>&gt;&gt;&gt; Write a predicate that takes a number and determines whether the sum of<br>&gt;&gt;&gt; its<br>&gt;&gt;&gt; digits is divisible by
 17.<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; Exercise 5.11<br>&gt;&gt;&gt; Write a procedure make-verifier, which takes f and m as its two arguments<br>&gt;&gt;&gt; and returns a procedure capable of checking a number. The argument f is<br>&gt;&gt;&gt; itself a procedure of course. Here is a particularly simple example of a<br>&gt;&gt;&gt; verifier being made and used.<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; (define check-isbn (make-verifier * 11))<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; (check-isbn 0262010771)<br>&gt;&gt;&gt; #t<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; The value #t is the "true" value; it indicates that the number is a valid<br>&gt;&gt;&gt; ISBN.<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; As we just saw, for ISBN numbers the divisor is 11 and the function is<br>&gt;&gt;&gt; simply f(i,d(i)) = i * d(i). Other kinds of numbers use slightly more<br>&gt;&gt;&gt; complicated functions, but you will still be able to use make-verifier to<br>&gt;&gt;&gt; make a verifier much more easily
 than if you had to start from scratch.<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; =======<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; Here's the Scheme check-verifier function I wrote, followed by my humble<br>&gt;&gt;&gt; attempt at a Haskell function that does the same thing. Below that are<br>&gt;&gt;&gt; some<br>&gt;&gt;&gt; verifier functions created with the Scheme make-verifier. Admittedly,<br>&gt;&gt;&gt; functions that return functions are Lispy, but perhaps there a Haskelly<br>&gt;&gt;&gt; way<br>&gt;&gt;&gt; to accomplish the same thing?<br>&gt;&gt;<br>&gt;&gt; Functions returning functions are quite natural in Haskell.<br>&gt;&gt; Since usually functions are written in curried form, a function returng a<br>&gt;&gt; function<br>&gt;&gt; corresponds to a function of multiple arguments applied to only some of<br>&gt;&gt; them.<br>&gt;&gt;<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; Michael<br>&gt;&gt;&gt;<br>&gt;&gt;&gt;
 ===============<br>&gt;&gt;&gt;<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; (define (make-verifier f m) ;f is f(i,d) &amp; m is divisor<br>&gt;&gt;&gt; &nbsp; (lambda (n)<br>&gt;&gt;&gt; &nbsp;&nbsp;&nbsp; (let* ((d (digits n))<br>&gt;&gt;&gt; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (i (index (length d))))&nbsp;&nbsp; ;(index 3) =&gt; (1 2 3)<br>&gt;&gt;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (divides? m (reduce + 0 (map f i d)))))) #f<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; makeVerifier :: (Int -&gt; Int -&gt;&nbsp; Int) -&gt; Int -&gt; (Int -&gt; Bool)<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; makeVerifier f m = \n -&gt; let d = digits n<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i = [1..(length d)]<br>&gt;&gt;&gt;<br>&gt;&gt;&gt;
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; in \n -&gt; divides m (foldl (+) 0 (map2 f i d))<br>&gt;&gt;&gt;<br>&gt;&gt;&gt;<br>&gt;&gt;<br>&gt;&gt; makeVerifier f m n = divides m . foldl (+) 0 $ zipWith f [1 .. ] (digits<br>&gt;&gt; n)<br>&gt;&gt;<br>&gt;&gt; just call makeVerifier f m to get your verification function :)<br>&gt;&gt;<br>&gt;&gt; If you don't want to name the last argument:<br>&gt;&gt;<br>&gt;&gt; makeVerifier f m = divides m . foldl (+) 0 . zipWith f [1 .. ] . digits<br>&gt;&gt;<br>&gt;&gt; more point-freeing would be obfuscation.<br>&gt;&gt; Instead of foldl (+) 0, you could also just write sum.<br>&gt;&gt;<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; -- Note: Reduce is just foldl f 0 lst, but map2 is<br>&gt;&gt;&gt; map2 :: (Int -&gt; Int -&gt; Int) -&gt; [Int] -&gt; [Int] -&gt; [Int]<br>&gt;&gt;&gt; map2 f m n = [ f i d | (i,d) &lt;- zip m
 n]<br>&gt;&gt;<br>&gt;&gt; map2 is zipWith, already in the Prelude.<br>&gt;&gt;<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; -- And here's my digits function<br>&gt;&gt;&gt; digits :: Int -&gt; [Int]<br>&gt;&gt;&gt; digits 0 = []<br>&gt;&gt;&gt; digits n = rem n 10 : digits (quot n 10)<br>&gt;&gt;<br>&gt;&gt; Unless you are desperate for speed and sure you deal only with positive<br>&gt;&gt; numbers (or know<br>&gt;&gt; that you really want quot and rem), better use div and mod. Those give the<br>&gt;&gt; commonly<br>&gt;&gt; expected (unless your expectation has been ruined by the behaviour of % in<br>&gt;&gt; C, Java...)<br>&gt;&gt; results.<br>&gt;&gt;<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; -- And divides function<br>&gt;&gt;&gt; divides :: Int -&gt; Int -&gt; Bool<br>&gt;&gt;&gt; divides divisor n = 0 == rem n divisor<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; =====<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; (define check-isbn ;book number<br>&gt;&gt;&gt; &nbsp;
 (make-verifier<br>&gt;&gt;&gt; &nbsp;&nbsp; *<br>&gt;&gt;&gt; &nbsp;&nbsp; 11))<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; (define check-upc ;universal product code<br>&gt;&gt;&gt; &nbsp; (make-verifier<br>&gt;&gt;&gt; &nbsp;&nbsp; (lambda (i d) (if (odd? i) d (* 3 d)))<br>&gt;&gt;&gt; &nbsp;&nbsp; 10))<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; (define check-cc ;credit card<br>&gt;&gt;&gt; &nbsp; (make-verifier<br>&gt;&gt;&gt; &nbsp;&nbsp; (lambda (i d) (if (odd? i) d (if (&lt; d 5) (* 2 d) (+ (* 2 d) 1))))<br>&gt;&gt;&gt; &nbsp;&nbsp; 10))<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; (define check-usps ;postal money order<br>&gt;&gt;&gt; &nbsp; (make-verifier<br>&gt;&gt;&gt; &nbsp;&nbsp; (lambda (i d) (if (= i 1) (- d) d))<br>&gt;&gt;&gt; &nbsp;&nbsp; 9))<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt; _______________________________________________<br>&gt;&gt; Haskell-Cafe mailing list<br>&gt;&gt; <a ymailto="mailto:Haskell-Cafe@haskell.org"
 href="/mc/compose?to=Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>&gt;&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>&gt;&gt;<br>&gt;&gt;<br>&gt;<br>&gt;<br>&gt; _______________________________________________<br>&gt; Haskell-Cafe mailing list<br>&gt; <a ymailto="mailto:Haskell-Cafe@haskell.org" href="/mc/compose?to=Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>&gt;<br>&gt;<br></div></blockquote></td></tr></table><br>