forked from ijp/ijputils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfunctions.sls
110 lines (91 loc) · 2.35 KB
/
functions.sls
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!r6rs
(library (ijputils functions)
(export compose
flip
id
identity ; alias
constant
constantly ; alias
complement
negate ; alias
always
never
on
;; inspired by racket
conjoin
disjoin
call
papply
papplyr
curryn
currynr
eta
eta*
)
(import (rnrs base)
(only (ijputils common) define-syntax-rule))
(define (compose . funs)
(lambda args
(let loop ((args args) (funs (reverse funs)))
(if (null? funs)
(apply values args)
(let-values ((vals (apply (car funs) args)))
(loop vals (cdr funs)))))))
(define (flip fn)
(lambda args
(apply fn (reverse args))))
(define (id x) x)
(define identity id)
(define (constant n)
(lambda args n))
;; someone suggested constantly, and I like it, but I'm still not sure
(define constantly constant)
(define (complement proc)
(lambda args
(not (apply proc args))))
(define negate complement)
(define always (constantly #t))
(define never (constantly #f))
(define (on binop f)
;; a specialisation of 'fork' matching haskell's on from Data.Function
(lambda (x y)
(binop (f x) (f y))))
;;; functions/macros originally from http://docs.racket-lang.org/unstable/Functions.html
(define (conjoin . preds)
(lambda args
(for-all (lambda (f) (apply f args)) preds)))
(define (disjoin . preds)
(lambda args
(exists (lambda (f) (apply f args)) preds)))
(define (call x . y)
(apply x y))
(define (papply f . args-l)
(lambda args-r
(apply f (append args-l args-r))))
(define (papplyr f . args-r)
(lambda args-l
(apply f (append args-l args-r))))
;; racket/function also has curry and curryr, but these seem to
;; require knowledge of how many parameters a function can have
(define (curryn n f . xs)
(let loop ((n n) (xs xs))
(if (zero? n)
(apply f xs)
(lambda ys
(loop (- n 1)
(append xs ys))))))
(define (currynr n f . xs)
(let loop ((n n) (xs xs))
(if (zero? n)
(apply f xs)
(lambda ys
(loop (- n 1)
(append ys xs))))))
(define-syntax-rule (eta exp)
(lambda args
(apply exp args)))
(define-syntax-rule (eta* f x ...)
(lambda (x ...)
;; remember f gets evaluated every time
(f x ...)))
)