[plt-scheme] Re: matching/dispatching a la Erlang
>>>>> "JAS" == Jens Axel Søgaard <jensaxel at soegaard.net> writes:
JAS> For list-related administrative tasks:
JAS> http://list.cs.brown.edu/mailman/listinfo/plt-scheme
JAS> William Sprague wrote:
>> I want to be able to do something like the following, where
>> "case-on-steroids" is my desired operator:
>>
>> (define (choose input)
>> (case-on-steroids (X Y) ; define X and Y as free variables
>> ((X X Y) (+ X Y)) ; matches (input 1 1 2), bind X->1, Y-
>> >2 ((1 X (2 Y) X) (* X Y)) ; matches (input 1 100 '(2 300)
>> 100) ; X->100, Y->300
>> (_ 'whatever)))) ; matches anything no bindings
JAS> Here is my take on your example:
[`chose' implemented above in a not-so-sexy way]
JAS> If there is an easier way to express that the two values
JAS> called x1 and x2 above must be equal - I'd like to see it.
Thanks to this thread, I've been inspired to check out the whole match
package further. I've learned two things:
(1) There's a site dedicated to maintaining the match code, which gives
some examples of its use and provides a manual that also gives lots
of info. Check it out at:
http://sol.cs.wcu.edu/~bhauman/scheme/pattern.php
(2) The most recent version of the match code, distributed with
plt-scheme 205, supports the ability to use two variables of the
same name to imply equality. (I think a previous poster mentioned
that this new functionality was in v205, but was a bit ambiguous
about what exactly *was* possible). [1]
Given my new found knowledge I translated a few examples that I've seen
in Erlang into scheme (I've included them below). This seemed to work
out pretty well, and perhaps I'll try to use pattern matching in my next
project...
-Ben
[1] -- Hmmm, I couldn't get the match code with v205 to work, instead I
had to use the match package from the site listed above. Either way, I
got it to work.
;------------------------------------------------------------------------
;;
;; Ben play's with pattern matching:
;;
; I had to use the latest version of match
; from http://sol.cs.wcu.edu/~bhauman/scheme/pattern.php
(require (lib "match.ss" "match-2-1"))
(define (choose input)
(match input
[(1 x (2 y)) (* x y)]
[(x x y) (+ x y)]
[_ 'whatever]))
(choose '(1 2 (2 100))) ; => 200
(choose '(3 3 9)) ; => 12
(choose '(3 4 9)) ; => 'whatever
(define member?
(match-lambda* [(x (x . _)) #t]
[(x (_ . y)) (member? x y)]
[(x ()) #f]))
(member? 10 '(1 2 3 10 9 8)) ; => #t
(member? 'foo '(1 2 3 10 9 8)) ; => #f
(member? 10 '()) ; => #f
(define fact
(match-lambda
[0 1]
[x (* x (fact (- x 1)))]))
(fact 0) ; => 1
(fact 9) ; => 362880
(fact 3) ; => 6
(define area
(match-lambda
[('square x) (* x x)]
[('rectangle x y) (* x y)]
[('circle r) (* 3.14 r r)]))
(define *shapes*
'((square 5)
(rectangle 3 4)
(circle 9)))
(map area *shapes*) ; => (25 12 235.34)