[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Learning the match-syntax...
From: |
swedebugia |
Subject: |
Learning the match-syntax... |
Date: |
Sat, 05 Jan 2019 13:25:40 -0800 |
Saluton Ludo' :)
I write this to you for no other reason than I like the code your write
and would love to learn more.
If you don't have time/energy just let me know and I will ask Pierre or
somebody else. :)
On 2019-01-05 18:39, Ludovic Courtès wrote:
> One last thing:
>
>> +(define (check-source-unstable-tarball package)
>> + "Emit a warning if PACKAGE's source is an autogenerated tarball."
>> + (define (check-source-uri uri)
>> + (when (and (string=? (uri-host (string->uri uri)) "github.com")
>> + (string=? (third (split-and-decode-uri-path
>> + (uri-path (string->uri uri))))
>> + "archive"))
>
> ‘third’ could fail badly if the list has fewer elements, so I’d suggest
> writing it something like:
>
> (when (and …
> (match (split-and-decode-uri-path …)
> ((_ _ "archive" _ ...) #t)
> (_ #f)))
> …)
This is an elegant rewrite to return a boolean #f in case the URL is bad
in some way.
I'm trying very hard to learn the guile match-syntax.
To make sure I understand the above I would like to explain it and you
can verify that I got it right. Ok?
> (match (split-and-decode-uri-path …) <- this is the input
> ((_ _ "archive" _ ...) #t)
^ ^ ^ =third ^ ^return true if the clause
match
^fourth & more
^ ^ = anything twice
> (_ #f)))
^ =the general case =else return #f.
Correct?
This is a more complicated (nested) match example from Juliens opam
importer which I find is an elegant functional way to find what we need:
(define (metadata-ref file lookup)
(fold (lambda (record acc)
(match record
((record key val)
(if (equal? key lookup)
(match val
(('list-pat . stuff) stuff)
(('string-pat stuff) stuff)
(('multiline-string stuff) stuff)
(('dict records ...) records))
acc))))
#f file))
(define (metadata-ref file lookup)
^ 2 arguments
(fold (lambda (record acc)
^2 formals, why the acc?
(match record
^input
((record key val)
^match "record" "key" "val" in a list?
(if (equal? key lookup)
^ we continue if the key is right
(match val
^input
(('list-pat . stuff) stuff)
^ if 'list-pat return stuff
(('string-pat stuff) stuff)
^ if 'string-pat return stuff
(('multiline-string stuff) stuff)
(('dict records ...) records))
^if 'dict return first record
acc))))
^ this is the else (what is this good for?)
#f file))
^ input to fold
^ no initial in the fold
If I understood this correctly I hope I will be able to get something
like this to work in the quicklisp importer :)
--
Cheers
Swedebugia