utils: Move compose-related functions to their own section.

This commit is contained in:
Sergiu Ivanov 2020-12-12 23:35:40 +01:00
parent f68731cf46
commit 6a38d1a5d3
2 changed files with 48 additions and 35 deletions

View file

@ -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)])]{

View file

@ -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