From 3bb695e2cf01b35fb5df46e2895bd11026f784a2 Mon Sep 17 00:00:00 2001 From: Sergiu Ivanov Date: Sat, 12 Dec 2020 23:35:40 +0100 Subject: [PATCH] utils: Move compose-related functions to their own section. --- scribblings/utils.scrbl | 52 ++++++++++++++++++++++++----------------- utils.rkt | 31 +++++++++++++----------- 2 files changed, 48 insertions(+), 35 deletions(-) diff --git a/scribblings/utils.scrbl b/scribblings/utils.scrbl index a713a96..b59123b 100644 --- a/scribblings/utils.scrbl +++ b/scribblings/utils.scrbl @@ -3,7 +3,7 @@ (for-label racket/base graph "../utils.rkt" (only-in typed/racket/base Any AnyValues Listof String Sexp Number Pair - List -> + List -> compose cast))) @title[#:tag "utils"]{dds/utils: Various Utilities} @@ -120,6 +120,35 @@ passed in the first argument. } +@section{Composing typed functions} + +Typed Racket's @racket[compose] only takes two arguments, because in general it +is difficult to specify that the return types and the argument types should be +the same for two successive functions in the argument list. This section +defines some further utilities which make using @racket[compose] +more comfortable. + +@defproc[(compose-n [proc (-> a a)] ...) (-> a a)]{ + +Compose an arbitrary number of functions of type @racket[(-> a a)]. + +@examples[#:eval utils-evaluator +((compose-n add1 add1 add1) 3) +]} + +@defproc*[([(compose-3 [proc1 (-> c d)] [proc2 (-> b c)] [proc3 (-> a b)]) (-> a d)] + [(compose-4 [proc1 (-> d e)] [proc2 (-> c d)] [proc3 (-> b c)] [proc4 (-> a b)]) (-> a e)])]{ + +@racket[compose-i] composes @racket[i] functions. The rightmost function is +applied first. + +@examples[#:eval utils-evaluator +(define (s->n [x : String]) (cast (string->number x) Number)) +(define fancy-add1 (compose-3 print add1 s->n)) +fancy-add1 +(fancy-add1 "1") +]} + @section{Org-mode interoperability} Org-mode supports laying out the output of code blocks as tables, which is very @@ -199,27 +228,6 @@ element with @racket[string->any] or keeps it as is if it is not a string. (unstringify-pairs '(("a" . 1) ("b" . "(and a (not b))"))) ]} -@defproc[(compose-n [proc (-> a a)] ...) (-> a a)]{ - -Compose an arbitrary number of functions of type @racket[(-> a a)]. - -@examples[#:eval utils-evaluator -((compose-n add1 add1 add1) 3) -]} - -@defproc*[([(compose-3 [proc1 (-> c d)] [proc2 (-> b c)] [proc3 (-> a b)]) (-> a d)] - [(compose-4 [proc1 (-> d e)] [proc2 (-> c d)] [proc3 (-> b c)] [proc4 (-> a b)]) (-> a e)])]{ - -@racket[compose-i] composes @racket[i] functions. The rightmost function is -applied first. - -@examples[#:eval utils-evaluator -(define (s->n [x : String]) (cast (string->number x) Number)) -(define fancy-add1 (compose-3 print add1 s->n)) -fancy-add1 -(fancy-add1 "1") -]} - @defproc*[([(read-org-variable-mapping [str String]) (VariableMapping Any)] [(unorgv [str String]) (VariableMapping Any)])]{ diff --git a/utils.rkt b/utils.rkt index 0222f4a..135fceb 100644 --- a/utils.rkt +++ b/utils.rkt @@ -129,6 +129,24 @@ '(x y z)))) +;;; ========================= +;;; Composing typed functions +;;; ========================= + +(: compose-n (All (a) (-> (-> a a) * (-> a a)))) +(define (compose-n . funcs) + (λ (x) + (for/foldr ([x x]) ([f funcs]) + (f x)))) + +(: compose-3 (All (a b c d) (-> (-> c d) (-> b c) (-> a b) (-> a d)))) +(define (compose-3 f1 f2 f3) + (λ (x) (f1 (f2 (f3 x))))) +(: compose-4 (All (a b c d e) (-> (-> d e) (-> c d) (-> b c) (-> a b) (-> a e)))) +(define (compose-4 f1 f2 f3 f4) + (λ (x) (f1 (f2 (f3 (f4 x)))))) + + ;;; ========================= ;;; Org-mode interoperability ;;; ========================= @@ -226,19 +244,6 @@ (check-equal? (unstringify-pairs '(("a" . 1) ("b" . "(and a (not b))"))) '((a . 1) (b . (and a (not b))))))) -(: compose-n (All (a) (-> (-> a a) * (-> a a)))) -(define (compose-n . funcs) - (λ (x) - (for/foldr ([x x]) ([f funcs]) - (f x)))) - -(: compose-3 (All (a b c d) (-> (-> c d) (-> b c) (-> a b) (-> a d)))) -(define (compose-3 f1 f2 f3) - (λ (x) (f1 (f2 (f3 x))))) -(: compose-4 (All (a b c d e) (-> (-> d e) (-> c d) (-> b c) (-> a b) (-> a e)))) -(define (compose-4 f1 f2 f3 f4) - (λ (x) (f1 (f2 (f3 (f4 x)))))) - (: read-org-variable-mapping (-> String (VariableMapping Any))) (define read-org-variable-mapping (compose-3