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