From ec849246086c7968aa3790f3295652f3a21cf38a Mon Sep 17 00:00:00 2001 From: Sergiu Ivanov Date: Sun, 23 Jan 2022 15:50:06 +0100 Subject: [PATCH] utils: Type map-sexp. --- scribblings/utils.scrbl | 15 ++++++++++++++- utils.rkt | 32 ++++++++++++++------------------ 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/scribblings/utils.scrbl b/scribblings/utils.scrbl index b12c662..036b6a2 100644 --- a/scribblings/utils.scrbl +++ b/scribblings/utils.scrbl @@ -2,7 +2,7 @@ @(require scribble/example racket/sandbox (for-label racket graph (submod "../utils.rkt" typed) (only-in typed/racket/base - Any AnyValues Listof Symbol String))) + Any AnyValues Listof Symbol String Number Sexp cast))) @title[#:tag "utils"]{dds/utils: Various Utilities} @@ -164,6 +164,19 @@ Reads any value from string. (string->any "(or b (not a))") ]} +@defproc[(map-sexp [func (-> Any Any)] [sexp Any]) Any]{ + +Given a @racket[Sexp], applies the @racket[func] to any object which is not +a list. + +@racket[map-sexp] will not check whether @racket[func] is indeed applicable to +every non-list element of @racket[sexp]. If this is not the case, a contract +violation for func will be generated. + +@examples[#:eval utils-evaluator +(map-sexp (λ (x) (add1 (cast x Number))) '(1 2 (4 10) 3)) +]} + @section{Additional graph utilities} @section{Pretty printing} diff --git a/utils.rkt b/utils.rkt index 2221b46..a4452b5 100644 --- a/utils.rkt +++ b/utils.rkt @@ -16,7 +16,7 @@ (provide eval-with eval1-with auto-hash-ref/explicit auto-hash-ref/: extract-symbols any->string stringify-variable-mapping string->any - handle-org-booleans) + handle-org-booleans map-sexp) (define-type Variable Symbol) (define-type (VariableMapping A) (Immutable-HashTable Variable A)) @@ -172,18 +172,29 @@ (check-equal? (handle-org-booleans "#f") #f) (check-equal? (handle-org-booleans '("#t" "#f")) '(#t #f)) (check-equal? (handle-org-booleans "t") "t"))) + + (: map-sexp (-> (-> Any Any) Any Any)) + (define (map-sexp func sexp) + (match sexp + [(? list?) (map ((curry map-sexp) func) sexp)] + [datum (func datum)])) + + (module+ test + (test-case "map-sexp" + (check-equal? (map-sexp (λ (x) (add1 (cast x Number))) '(1 2 (4 10) 3)) + '(2 3 (5 11) 4)))) ) (require 'typed) (provide eval-with eval1-with auto-hash-ref/explicit auto-hash-ref/: - extract-symbols any->string stringify-variable-mapping string->any) + extract-symbols any->string stringify-variable-mapping string->any + map-sexp) ;;; Untyped section. (provide ;; Functions (contract-out [read-org-sexp (-> string? (listof any/c))] - [map-sexp (-> procedure? any/c any/c)] [unorg (-> string? (listof any/c))] [unstringify-pairs (-> (listof (general-pair/c string? any/c)) (listof (general-pair/c symbol? any/c)))] @@ -232,21 +243,6 @@ ;;; A string variable mapping is a mapping from variables to strings. (define (string-variable-mapping? dict) (hash/c symbol? string?)) -;;; Given a sexp, applies the given function to any object which is -;;; not a list. -;;; -;;; The contract of this function will not check whether func is -;;; indeed applicable to every non-list element of the sexp. If this -;;; is not the case, a contract violation for func will be generated. -(define (map-sexp func sexp) - (match sexp - [(? list?) (map ((curry map-sexp) func) sexp)] - [datum (func datum)])) - -(module+ test - (test-case "map-sexp" - (check-equal? (map-sexp add1 '(1 2 (4 10) 3)) '(2 3 (5 11) 4)))) - ;;; Reads a sexp from a string produced by Org-mode for a named table. ;;; See example.org for examples. (define read-org-sexp