<table cellspacing="0" cellpadding="0" border="0" ><tr><td valign="top" style="font: inherit;">Example please.<br><br>Michael<br><br>--- On <b>Sun, 4/12/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, "Daniel Fischer" &lt;daniel.is.fischer@web.de&gt;<br>Date: Sunday, April 12, 2009, 6:59 PM<br><br><div class="plainMail">You should use an curried function as f instead of a uncurried one.<br>Uncurried functions are rarely used in Haskell.<br><br>&nbsp; -- Lennart<br><br>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; Thanks, guys!<br>&gt;<br>&gt; Boy, this bunch of complemented partially applied functions gives a whole<br>&gt; new meaning to the term "thinking ahead." And the whole shebang is waiting<br>&gt; on that input integer to set everything in motion. Pretty clever.<br>&gt;<br>&gt;<br>&gt; To generalize, I changed the function to:<br>&gt;<br>&gt; makeVerifier :: ((Int,Int) -&gt; Int) -&gt; Int -&gt; (Int -&gt; Bool)<br>&gt; makeVerifier f m = divides m . foldl (+) 0 . map f . zip [1 .. ] . digits<br>&gt;<br>&gt; so, in Haskell<br>&gt;<br>&gt; let checkIsbn = makeVerifier (\ (i,d) -&gt; i * d) 11<br>&gt;<br>&gt; let checkUpc = makeVerifier (\ (i,d) -&gt; if odd i then d else 3*d) 10<br>&gt;<br>&gt; let checkCc = makeVerifier (\ (i,d) -&gt; if odd i then d else if d &lt; 5 then<br>&gt; 2*d else 2*d+1) 10<br>&gt;<br>&gt; let checkUsps = makeVerifier (\ (i,d) -&gt; if i == 1 then -d else d) 9<br>&gt;<br>&gt;<br>&gt; I think I'm catching
 on.<br>&gt;<br>&gt; Michael<br>&gt;<br>&gt;<br>&gt;<br>&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;<br>&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; Subject: Re: [Haskell-cafe] Functions that return functions<br>&gt; To: <a ymailto="mailto:haskell-cafe@haskell.org" href="/mc/compose?to=haskell-cafe@haskell.org">haskell-cafe@haskell.org</a><br>&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; Date: Sunday, April 12, 2009, 12:15 PM<br>&gt;<br>&gt; Am Sonntag 12 April 2009 17:38:53 schrieb michael rice:<br>&gt;&gt; The following are exercises 5.10, and 5.11 from the Scheme text "Concrete<br>&gt;&gt; Abstractions" by
 Max Hailperin, et al. The text at that point is about<br>&gt;&gt; writing verifiers to check ID numbers such as ISBNs, credit card numbers,<br>&gt;&gt; UPCs, etc.<br>&gt;&gt;<br>&gt;&gt; ======<br>&gt;&gt;<br>&gt;&gt; Exercise 5.10<br>&gt;&gt; Write a predicate that takes a number and determines whether the sum of<br>&gt;&gt; its<br>&gt;&gt; digits is divisible by 17.<br>&gt;&gt;<br>&gt;&gt; Exercise 5.11<br>&gt;&gt; Write a procedure make-verifier, which takes f and m as its two arguments<br>&gt;&gt; and returns a procedure capable of checking a number. The argument f is<br>&gt;&gt; itself a procedure of course. Here is a particularly simple example of a<br>&gt;&gt; verifier being made and used.<br>&gt;&gt;<br>&gt;&gt; (define check-isbn (make-verifier * 11))<br>&gt;&gt;<br>&gt;&gt; (check-isbn 0262010771)<br>&gt;&gt; #t<br>&gt;&gt;<br>&gt;&gt; The value #t is the "true" value; it indicates that the number is a valid<br>&gt;&gt;
 ISBN.<br>&gt;&gt;<br>&gt;&gt; As we just saw, for ISBN numbers the divisor is 11 and the function is<br>&gt;&gt; simply f(i,d(i)) = i * d(i). Other kinds of numbers use slightly more<br>&gt;&gt; complicated functions, but you will still be able to use make-verifier to<br>&gt;&gt; make a verifier much more easily than if you had to start from scratch.<br>&gt;&gt;<br>&gt;&gt; =======<br>&gt;&gt;<br>&gt;&gt; Here's the Scheme check-verifier function I wrote, followed by my humble<br>&gt;&gt; attempt at a Haskell function that does the same thing. Below that are<br>&gt;&gt; some<br>&gt;&gt; verifier functions created with the Scheme make-verifier. Admittedly,<br>&gt;&gt; functions that return functions are Lispy, but perhaps there a Haskelly<br>&gt;&gt; way<br>&gt;&gt; to accomplish the same thing?<br>&gt;<br>&gt; Functions returning functions are quite natural in Haskell.<br>&gt; Since usually functions are written in curried form, a function returng
 a<br>&gt; function<br>&gt; corresponds to a function of multiple arguments applied to only some of<br>&gt; them.<br>&gt;<br>&gt;&gt;<br>&gt;&gt; Michael<br>&gt;&gt;<br>&gt;&gt; ===============<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt; (define (make-verifier f m) ;f is f(i,d) &amp; m is divisor<br>&gt;&gt; &nbsp; (lambda (n)<br>&gt;&gt; &nbsp;&nbsp;&nbsp; (let* ((d (digits n))<br>&gt;&gt; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (i (index (length d))))&nbsp;&nbsp; ;(index 3) =&gt; (1 2 3)<br>&gt;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (divides? m (reduce + 0 (map f i d)))))) #f<br>&gt;&gt;<br>&gt;&gt; makeVerifier :: (Int -&gt; Int -&gt;&nbsp; Int) -&gt; Int -&gt; (Int -&gt; Bool)<br>&gt;&gt;<br>&gt;&gt; makeVerifier f m = \n -&gt; let d = digits n<br>&gt;&gt;<br>&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;<br>&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;<br>&gt;&gt;<br>&gt;<br>&gt; makeVerifier f m n = divides m . foldl (+) 0 $ zipWith f [1 .. ] (digits n)<br>&gt;<br>&gt; just call makeVerifier f m to get your verification function :)<br>&gt;<br>&gt; If you don't want to name the last argument:<br>&gt;<br>&gt; makeVerifier f m = divides m . foldl (+) 0 . zipWith f [1 .. ] . digits<br>&gt;<br>&gt; more point-freeing would be obfuscation.<br>&gt; Instead of foldl (+) 0, you could also just write sum.<br>&gt;<br>&gt;&gt;<br>&gt;&gt; -- Note: Reduce is just foldl f 0 lst, but map2 is<br>&gt;&gt; map2 :: (Int -&gt; Int -&gt; Int) -&gt; [Int] -&gt; [Int] -&gt; [Int]<br>&gt;&gt; map2 f m n = [ f i d | (i,d) &lt;- zip m n]<br>&gt;<br>&gt; map2 is zipWith, already in the
 Prelude.<br>&gt;<br>&gt;&gt;<br>&gt;&gt; -- And here's my digits function<br>&gt;&gt; digits :: Int -&gt; [Int]<br>&gt;&gt; digits 0 = []<br>&gt;&gt; digits n = rem n 10 : digits (quot n 10)<br>&gt;<br>&gt; Unless you are desperate for speed and sure you deal only with positive<br>&gt; numbers (or know<br>&gt; that you really want quot and rem), better use div and mod. Those give the<br>&gt; commonly<br>&gt; expected (unless your expectation has been ruined by the behaviour of % in<br>&gt; C, Java...)<br>&gt; results.<br>&gt;<br>&gt;&gt;<br>&gt;&gt; -- And divides function<br>&gt;&gt; divides :: Int -&gt; Int -&gt; Bool<br>&gt;&gt; divides divisor n = 0 == rem n divisor<br>&gt;&gt;<br>&gt;&gt; =====<br>&gt;&gt;<br>&gt;&gt; (define check-isbn ;book number<br>&gt;&gt; &nbsp; (make-verifier<br>&gt;&gt; &nbsp;&nbsp; *<br>&gt;&gt; &nbsp;&nbsp; 11))<br>&gt;&gt;<br>&gt;&gt; (define check-upc ;universal product code<br>&gt;&gt; &nbsp; (make-verifier<br>&gt;&gt;
 &nbsp;&nbsp; (lambda (i d) (if (odd? i) d (* 3 d)))<br>&gt;&gt; &nbsp;&nbsp; 10))<br>&gt;&gt;<br>&gt;&gt; (define check-cc ;credit card<br>&gt;&gt; &nbsp; (make-verifier<br>&gt;&gt; &nbsp;&nbsp; (lambda (i d) (if (odd? i) d (if (&lt; d 5) (* 2 d) (+ (* 2 d) 1))))<br>&gt;&gt; &nbsp;&nbsp; 10))<br>&gt;&gt;<br>&gt;&gt; (define check-usps ;postal money order<br>&gt;&gt; &nbsp; (make-verifier<br>&gt;&gt; &nbsp;&nbsp; (lambda (i d) (if (= i 1) (- d) d))<br>&gt;&gt; &nbsp;&nbsp; 9))<br>&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>