Compare commits
No commits in common. "69de45761367a99ee919ba84c33abddb06419e87" and "bfa82e3cb268e77efe7e71f90ad669098d31a055" have entirely different histories.
69de457613
...
bfa82e3cb2
109
main.rkt
109
main.rkt
|
@ -16,17 +16,11 @@
|
||||||
;;; along with this program. If not, see
|
;;; along with this program. If not, see
|
||||||
;;; <https://www.gnu.org/licenses/>.
|
;;; <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#lang typed/racket/base
|
#lang typed/racket
|
||||||
|
|
||||||
(require syntax/parse/define
|
(require (for-syntax syntax/parse))
|
||||||
(for-syntax racket/base
|
|
||||||
racket/match
|
|
||||||
racket/list
|
|
||||||
racket/syntax
|
|
||||||
syntax/parse))
|
|
||||||
|
|
||||||
(provide make-compose
|
(provide compose-n
|
||||||
compose-n
|
|
||||||
compose-3 compose-4 compose-5 compose-6 compose-7 compose-8 compose-9
|
compose-3 compose-4 compose-5 compose-6 compose-7 compose-8 compose-9
|
||||||
multi-compose multi-chain)
|
multi-compose multi-chain)
|
||||||
|
|
||||||
|
@ -43,30 +37,82 @@
|
||||||
(test-case "compose-n"
|
(test-case "compose-n"
|
||||||
(check-equal? ((compose-n add1 add1 add1) 3) 6)))
|
(check-equal? ((compose-n add1 add1 add1) 3) 6)))
|
||||||
|
|
||||||
(define-for-syntax (make-compose-type n)
|
(: compose-3 (All (a b c d)
|
||||||
(with-syntax* ([(t ...) (generate-temporaries (make-list n 't))]
|
(-> (-> c d)
|
||||||
[(_ ... t₀) #'(a t ...)]
|
(-> b c)
|
||||||
[(F ...)
|
(-> a b)
|
||||||
(let step ([u #'a] [ts (syntax->list #'(t ...))])
|
(-> a d))))
|
||||||
(match ts
|
(define (compose-3 f1 f2 f3)
|
||||||
['() '()]
|
(λ (x) (f1 (f2 (f3 x)))))
|
||||||
[(cons t ts*) (cons #`(#,t → #,u) (step t ts*))]))])
|
|
||||||
#'(∀ (a t ...) (F ... → t₀ → a))))
|
|
||||||
|
|
||||||
(define-syntax-parser make-compose
|
(: compose-4 (All (a b c d e)
|
||||||
[(_ n:nat)
|
(-> (-> d e)
|
||||||
(with-syntax* ([(f ...) (generate-temporaries (make-list (syntax-e #'n) 'f))]
|
(-> c d)
|
||||||
[T (make-compose-type (syntax-e #'n))]
|
(-> b c)
|
||||||
[body (foldr (λ (fᵢ res) #`(#,fᵢ #,res)) #'x (syntax->list #'(f ...)))])
|
(-> a b)
|
||||||
#'(ann (λ (f ...) (λ (x) body)) T))])
|
(-> a e))))
|
||||||
|
(define (compose-4 f1 f2 f3 f4)
|
||||||
|
(λ (x) (f1 (f2 (f3 (f4 x))))))
|
||||||
|
|
||||||
(define compose-3 (make-compose 3))
|
(: compose-5 (All (a b c d e f)
|
||||||
(define compose-4 (make-compose 4))
|
(-> (-> e f)
|
||||||
(define compose-5 (make-compose 5))
|
(-> d e)
|
||||||
(define compose-6 (make-compose 6))
|
(-> c d)
|
||||||
(define compose-7 (make-compose 7))
|
(-> b c)
|
||||||
(define compose-8 (make-compose 8))
|
(-> a b)
|
||||||
(define compose-9 (make-compose 9))
|
(-> a f))))
|
||||||
|
(define (compose-5 f1 f2 f3 f4 f5)
|
||||||
|
(λ (x) (f1 (f2 (f3 (f4 (f5 x)))))))
|
||||||
|
|
||||||
|
(: compose-6 (All (a b c d e f g)
|
||||||
|
(-> (-> f g)
|
||||||
|
(-> e f)
|
||||||
|
(-> d e)
|
||||||
|
(-> c d)
|
||||||
|
(-> b c)
|
||||||
|
(-> a b)
|
||||||
|
(-> a g))))
|
||||||
|
(define (compose-6 f1 f2 f3 f4 f5 f6)
|
||||||
|
(λ (x) (f1 (f2 (f3 (f4 (f5 (f6 x))))))))
|
||||||
|
|
||||||
|
(: compose-7 (All (a b c d e f g h)
|
||||||
|
(-> (-> g h)
|
||||||
|
(-> f g)
|
||||||
|
(-> e f)
|
||||||
|
(-> d e)
|
||||||
|
(-> c d)
|
||||||
|
(-> b c)
|
||||||
|
(-> a b)
|
||||||
|
(-> a h))))
|
||||||
|
(define (compose-7 f1 f2 f3 f4 f5 f6 f7)
|
||||||
|
(λ (x) (f1 (f2 (f3 (f4 (f5 (f6 (f7 x)))))))))
|
||||||
|
|
||||||
|
(: compose-8 (All (a b c d e f g h i)
|
||||||
|
(-> (-> h i)
|
||||||
|
(-> g h)
|
||||||
|
(-> f g)
|
||||||
|
(-> e f)
|
||||||
|
(-> d e)
|
||||||
|
(-> c d)
|
||||||
|
(-> b c)
|
||||||
|
(-> a b)
|
||||||
|
(-> a i))))
|
||||||
|
(define (compose-8 f1 f2 f3 f4 f5 f6 f7 f8)
|
||||||
|
(λ (x) (f1 (f2 (f3 (f4 (f5 (f6 (f7 (f8 x))))))))))
|
||||||
|
|
||||||
|
(: compose-9 (All (a b c d e f g h i j)
|
||||||
|
(-> (-> i j)
|
||||||
|
(-> h i)
|
||||||
|
(-> g h)
|
||||||
|
(-> f g)
|
||||||
|
(-> e f)
|
||||||
|
(-> d e)
|
||||||
|
(-> c d)
|
||||||
|
(-> b c)
|
||||||
|
(-> a b)
|
||||||
|
(-> a j))))
|
||||||
|
(define (compose-9 f1 f2 f3 f4 f5 f6 f7 f8 f9)
|
||||||
|
(λ (x) (f1 (f2 (f3 (f4 (f5 (f6 (f7 (f8 (f9 x)))))))))))
|
||||||
|
|
||||||
(module+ test
|
(module+ test
|
||||||
(test-case "compose-3 to compose-9"
|
(test-case "compose-3 to compose-9"
|
||||||
|
@ -106,7 +152,6 @@
|
||||||
#`(multi-compose #,@rev-funcs)]))
|
#`(multi-compose #,@rev-funcs)]))
|
||||||
|
|
||||||
(module+ test
|
(module+ test
|
||||||
(require racket/port)
|
|
||||||
(test-case "multi-chain and multi-compose"
|
(test-case "multi-chain and multi-compose"
|
||||||
(define f1 (λ ([x : Number]) (displayln "f1") (+ x 1)))
|
(define f1 (λ ([x : Number]) (displayln "f1") (+ x 1)))
|
||||||
(define f2 (λ ([x : Number]) (displayln "f2") (+ x 1)))
|
(define f2 (λ ([x : Number]) (displayln "f2") (+ x 1)))
|
||||||
|
|
12
manual.scrbl
12
manual.scrbl
|
@ -65,18 +65,6 @@ fancy-add1
|
||||||
(fancy-add1 "1")
|
(fancy-add1 "1")
|
||||||
]}
|
]}
|
||||||
|
|
||||||
@section{Macros for composing functions}
|
|
||||||
|
|
||||||
@defform[(make-compose n)
|
|
||||||
#:contracts ([n exact-nonnegative-integer])]{
|
|
||||||
|
|
||||||
Expants to a typed @racket[lambda] form composing exactly @racket[n]
|
|
||||||
one-argument functions. For example, @racket[compose-3] is defined as:
|
|
||||||
@racket[(define compose-3 (make-compose 3))]. The rest of the functions of the
|
|
||||||
@racket[compose-i] family are defined using this macro as well.
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@defform[(multi-compose func ...)
|
@defform[(multi-compose func ...)
|
||||||
#:contracts ([func expression])]{
|
#:contracts ([func expression])]{
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user