783 lines
17 KiB
Racket
783 lines
17 KiB
Racket
#lang racket
|
|
|
|
#|
|
|
|
|
Port of the rhs library to Racket used by scos and rsc3.
|
|
|
|
Written by Rohan Drape (http://rd.slavepianos.org/), © 2008-2012
|
|
|
|
http://rd.slavepianos.org/
|
|
|
|
Licensed under GPL (2 or 3? FIXME)
|
|
|
|
|
|
|#
|
|
|
|
(require rnrs)
|
|
|
|
(provide (all-defined-out))
|
|
|
|
|
|
;; to fix rnrs compatibility
|
|
|
|
#|
|
|
(define exact inexact->exact)
|
|
|
|
(define inexact exact->inexact)
|
|
|
|
(define mod remainder)
|
|
|#
|
|
|
|
;; JBC, 2014-- looks like most of these library functions have
|
|
;; equivalents in Racket....
|
|
|
|
|
|
;; prelude.scm ;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;; enumFromThenTo :: a -> a -> a -> [a]
|
|
(define enum-from-then-to
|
|
(letrec ((efdt
|
|
(lambda (f i x k)
|
|
(cond ((= i k) (list1 k))
|
|
((f i k) null)
|
|
(else (cons i (efdt f (+ i x) x k)))))))
|
|
(lambda (i j k)
|
|
(let ((x (- j i)))
|
|
(efdt (if (> x 0) > <) i x k)))))
|
|
|
|
;; enumFromTo :: a -> a -> [a]
|
|
(define enum-from-to
|
|
(lambda (i j)
|
|
(enum-from-then-to i (succ i) j)))
|
|
|
|
;; even :: (Integral a) => a -> Bool
|
|
(define even
|
|
even?)
|
|
|
|
;; odd :: (Integral a) => a -> Bool
|
|
(define odd
|
|
odd?)
|
|
|
|
;; pred :: a -> a
|
|
(define pred
|
|
(lambda (x)
|
|
(- x 1)))
|
|
|
|
;; signum :: Num a => a -> a
|
|
(define signum
|
|
(lambda (x)
|
|
(cond ((> x 0) 1)
|
|
((< x 0) -1)
|
|
(else 0))))
|
|
|
|
;; succ :: a -> a
|
|
(define succ
|
|
(lambda (x)
|
|
(+ x 1)))
|
|
|
|
;; undefined :: a
|
|
(define undefined
|
|
(lambda ()
|
|
(error "undefined" "undefined")))
|
|
|
|
|
|
|
|
;; tuple.scm ;;;;;;;;;;;;
|
|
|
|
|
|
;; curry :: ((a, b) -> c) -> a -> b -> c
|
|
(define curry
|
|
(lambda (f)
|
|
(lambda (x y)
|
|
(f (tuple2 x y)))))
|
|
|
|
(struct duple (p q))
|
|
|
|
;; fst :: (a, b) -> a
|
|
(define fst
|
|
duple-p)
|
|
|
|
;; snd :: (a, b) -> b
|
|
(define snd
|
|
duple-q)
|
|
|
|
;; (,) :: a -> b -> (a, b)
|
|
(define tuple2
|
|
duple)
|
|
|
|
;; uncurry :: (a -> b -> c) -> (a, b) -> c
|
|
(define uncurry
|
|
(lambda (f)
|
|
(lambda (xy)
|
|
(f (fst xy) (snd xy)))))
|
|
|
|
|
|
;; data/ord.scm ;;;;;;;;;;;;;;;;
|
|
|
|
|
|
;; data Ordering = LT | EQ | GT
|
|
|
|
;; compare :: (Ord a) => a -> a -> Ordering
|
|
(define compare
|
|
(lambda (x y)
|
|
(cond ((> x y) 'gt)
|
|
((< x y) 'lt)
|
|
(else 'eq))))
|
|
|
|
;; max :: a -> a -> a
|
|
(define max2
|
|
(lambda (x y)
|
|
(if (> x y) x y)))
|
|
|
|
;; min :: a -> a -> a
|
|
(define min2
|
|
(lambda (x y)
|
|
(if (< x y) x y)))
|
|
|
|
|
|
|
|
;; data/function.scm ;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
;; (.) :: (b -> c) -> (a -> b) -> a -> c
|
|
(define compose
|
|
(lambda (f g)
|
|
(lambda (x)
|
|
(f (g x)))))
|
|
|
|
;; const :: a -> b -> a
|
|
(define const
|
|
(lambda (x)
|
|
(lambda (_)
|
|
x)))
|
|
|
|
;; flip :: (a -> b -> c) -> b -> a -> c
|
|
(define flip
|
|
(lambda (f)
|
|
(lambda (x y)
|
|
(f y x))))
|
|
|
|
;; id :: a -> a
|
|
(define id
|
|
(lambda (x)
|
|
x))
|
|
|
|
|
|
|
|
;; data/list.scm ;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;; all :: (a -> Bool) -> [a] -> Bool
|
|
(define all
|
|
(lambda (f l)
|
|
(if (null? l)
|
|
#t
|
|
(and (f (head l)) (all f (tail l))))))
|
|
|
|
;; and :: [Bool] -> Bool
|
|
(define all-true
|
|
(lambda (l)
|
|
(if (null? l)
|
|
#t
|
|
(and (head l) (all-true (tail l))))))
|
|
|
|
;; any :: (a -> Bool) -> [a] -> Bool
|
|
(define any
|
|
(lambda (f l)
|
|
(if (null? l)
|
|
#f
|
|
(or (f (head l)) (any f (tail l))))))
|
|
|
|
;; (++) :: [a] -> [a] -> [a]
|
|
(define append2
|
|
(lambda (a b)
|
|
(if (null? a)
|
|
b
|
|
(cons (head a) (append2 (tail a) b)))))
|
|
|
|
;; break :: (a -> Bool) -> [a] -> ([a],[a])
|
|
(define break
|
|
(lambda (p l)
|
|
(span (compose not p) l)))
|
|
|
|
;; concat :: [[a]] -> [a]
|
|
(define concat
|
|
(lambda (l)
|
|
(foldr append2 nil l)))
|
|
|
|
;; concatMap :: (a -> [b]) -> [a] -> [b]
|
|
(define concat-map
|
|
(lambda (f l)
|
|
(concat (map1 f l))))
|
|
|
|
;; deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a]
|
|
(define delete-by
|
|
(lambda (f x l)
|
|
(if (null? l)
|
|
nil
|
|
(if (f x (head l))
|
|
(tail l)
|
|
(cons (head l) (delete-by f x (tail l)))))))
|
|
|
|
;; delete :: (Eq a) => a -> [a] -> [a]
|
|
(define delete
|
|
(lambda (x l)
|
|
(delete-by equal? x l)))
|
|
|
|
;; drop :: Int -> [a] -> [a]
|
|
(define drop
|
|
(lambda (n l)
|
|
(cond ((<= n 0) l)
|
|
((null? l) nil)
|
|
(else (drop (- n 1) (tail l))))))
|
|
|
|
;; dropWhile :: (a -> Bool) -> [a] -> [a]
|
|
(define drop-while
|
|
(lambda (p l)
|
|
(if (null? l)
|
|
nil
|
|
(if (p (head l))
|
|
(drop-while p (tail l))
|
|
l))))
|
|
|
|
;; elem :: (Eq a) => a -> [a] -> Bool
|
|
(define elem
|
|
(lambda (x l)
|
|
(any (lambda (y) (equal? x y)) l)))
|
|
|
|
;; elemIndex :: Eq a => a -> [a] -> Maybe Int
|
|
(define elem-index
|
|
(lambda (x l)
|
|
(find-index (lambda (y) (equal? x y)) l)))
|
|
|
|
;; elemIndices :: Eq a => a -> [a] -> [Int]
|
|
(define elem-indices
|
|
(lambda (x l)
|
|
(find-indices (lambda (y) (equal? x y)) l)))
|
|
|
|
;; find :: (a -> Bool) -> [a] -> Maybe a
|
|
#;(define find
|
|
(lambda (f l)
|
|
(if (null? l)
|
|
#f
|
|
(if (f (head l))
|
|
(head l)
|
|
(find f (tail l))))))
|
|
|
|
|
|
;; findIndex :: (a -> Bool) -> [a] -> Maybe Int
|
|
(define find-index
|
|
(letrec ((g (lambda (f l n)
|
|
(if (null? l)
|
|
#f
|
|
(if (f (head l))
|
|
n
|
|
(g f (tail l) (+ n 1)))))))
|
|
(lambda (f l)
|
|
(g f l 0))))
|
|
|
|
;; findIndices :: (a -> Bool) -> [a] -> [Int]
|
|
(define find-indices
|
|
(letrec ((g (lambda (f l n)
|
|
(if (null? l)
|
|
nil
|
|
(if (f (head l))
|
|
(cons n (g f (tail l) (+ n 1)))
|
|
(g f (tail l) (+ n 1)))))))
|
|
(lambda (f l)
|
|
(g f l 0))))
|
|
|
|
;; filter :: (a -> Bool) -> [a] -> [a]
|
|
#;(define filter
|
|
(lambda (f l)
|
|
(if (null? l)
|
|
nil
|
|
(let ((x (head l))
|
|
(xs (tail l)))
|
|
(if (f x)
|
|
(cons x (filter f xs))
|
|
(filter f xs))))))
|
|
|
|
;; foldl :: (a -> b -> a) -> a -> [b] -> a
|
|
(define foldl
|
|
(lambda (f z l)
|
|
(if (null? l)
|
|
z
|
|
(foldl f (f z (head l)) (tail l)))))
|
|
|
|
;; foldl1 :: (a -> a -> a) -> [a] -> a
|
|
(define foldl1
|
|
(lambda (f l)
|
|
(foldl f (head l) (tail l))))
|
|
|
|
;; foldr :: (a -> b -> b) -> b -> [a] -> b
|
|
(define foldr
|
|
(lambda (f z l)
|
|
(if (null? l)
|
|
z
|
|
(f (head l) (foldr f z (tail l))))))
|
|
|
|
;; foldr1 :: (a -> a -> a) -> [a] -> a
|
|
(define foldr1
|
|
(lambda (f l)
|
|
(if (null? (tail l))
|
|
(head l)
|
|
(f (head l) (foldr1 f (tail l))))))
|
|
|
|
;; groupBy :: (a -> a -> Bool) -> [a] -> [[a]]
|
|
(define group-by
|
|
(lambda (f l)
|
|
(if (null? l)
|
|
(list)
|
|
(let* ((x (car l))
|
|
(yz (span (lambda (e) (f e x)) (cdr l))))
|
|
(cons (cons x (fst yz)) (group-by f (snd yz)))))))
|
|
|
|
;; head :: [a] -> a
|
|
(define head car)
|
|
|
|
;; init :: [a] -> [a]
|
|
(define init
|
|
(lambda (l)
|
|
(let ((x (head l))
|
|
(xs (tail l)))
|
|
(if (null? xs)
|
|
nil
|
|
(cons x (init xs))))))
|
|
|
|
;; insert :: Ord a => a -> [a] -> [a]
|
|
(define insert
|
|
(lambda (e l)
|
|
(insert-by compare e l)))
|
|
|
|
;; insertBy :: (a -> a -> Ordering) -> a -> [a] -> [a]
|
|
(define insert-by
|
|
(lambda (f x l)
|
|
(if (null? l)
|
|
(list1 x)
|
|
(if (equal? (f x (head l)) 'gt)
|
|
(cons (head l) (insert-by f x (tail l)))
|
|
(cons x l)))))
|
|
|
|
;; intercalate :: [a] -> [[a]] -> [a]
|
|
(define intercalate
|
|
(lambda (xs xss)
|
|
(concat (intersperse xs xss))))
|
|
|
|
;; intersperse :: a -> [a] -> [a]
|
|
(define intersperse
|
|
(lambda (x l)
|
|
(cond ((null? l) nil)
|
|
((null? (tail l)) l)
|
|
(else (cons (head l) (cons x (intersperse x (tail l))))))))
|
|
|
|
;; isInfixOf :: (Eq a) => [a] -> [a] -> Bool
|
|
(define is-infix-of
|
|
(lambda (p q)
|
|
(cond ((null? p) #t)
|
|
((null? q) #f)
|
|
(else (or (is-prefix-of p q)
|
|
(is-infix-of p (tail q)))))))
|
|
|
|
;; isPrefixOf :: (Eq a) => [a] -> [a] -> Bool
|
|
(define is-prefix-of
|
|
(lambda (p q)
|
|
(cond ((null? p) #t)
|
|
((null? q) #f)
|
|
(else (and (equal? (head p) (head q))
|
|
(is-prefix-of (tail p) (tail q)))))))
|
|
|
|
;; isSuffixOf :: (Eq a) => [a] -> [a] -> Bool
|
|
(define is-suffix-of
|
|
(lambda (p q)
|
|
(is-prefix-of (reverse p) (reverse q))))
|
|
|
|
;; last :: [a] -> a
|
|
(define last
|
|
(lambda (l)
|
|
(let ((xs (tail l)))
|
|
(if (null? xs)
|
|
(head l)
|
|
(last xs)))))
|
|
|
|
;; mlength :: [a] -> Int
|
|
(define mlength
|
|
(lambda (l)
|
|
(if (null? l)
|
|
0
|
|
(+ 1 (length (tail l))))))
|
|
|
|
|
|
|
|
;; list1 :: a -> [a]
|
|
(define list1
|
|
(lambda (x)
|
|
(cons x nil)))
|
|
|
|
;; list2 :: a -> a -> [a]
|
|
(define list2
|
|
(lambda (x y)
|
|
(cons x (cons y nil))))
|
|
|
|
;; list3 :: a -> a -> a -> [a]
|
|
(define list3
|
|
(lambda (x y z)
|
|
(cons x (cons y (cons z nil)))))
|
|
|
|
;; list4 :: a -> a -> a -> a -> [a]
|
|
(define list4
|
|
(lambda (x y z a)
|
|
(cons x (cons y (cons z (cons a nil))))))
|
|
|
|
;; list5 :: a -> a -> a -> a -> a -> [a]
|
|
(define list5
|
|
(lambda (x y z a b)
|
|
(cons x (cons y (cons z (cons a (cons b nil)))))))
|
|
|
|
;; (!!) :: [a] -> Int -> a
|
|
#;(define list-ref
|
|
(lambda (l n)
|
|
(if (= n 0)
|
|
(head l)
|
|
(list-ref (tail l) (- n 1)))))
|
|
|
|
;; lookup :: (Eq a) => a -> [(a, b)] -> Maybe b
|
|
(define lookup
|
|
(lambda (x l)
|
|
(if (null? l)
|
|
#f
|
|
(if (equal? (fst (head l)) x)
|
|
(snd (head l))
|
|
(lookup x (tail l))))))
|
|
|
|
;; map :: (a -> b) -> [a] -> [b]
|
|
(define map1 map)
|
|
#;(define map1
|
|
(lambda (f l)
|
|
(if (null? l)
|
|
nil
|
|
(cons (f (head l)) (map1 f (tail l))))))
|
|
|
|
;; mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
|
|
(define map-accum-l
|
|
(lambda (f s l)
|
|
(if (null? l)
|
|
(tuple2 s nil)
|
|
(let* ((x (head l))
|
|
(xs (tail l))
|
|
(s_y (f s x))
|
|
(s_ (fst s_y))
|
|
(y (snd s_y))
|
|
(s__ys (map-accum-l f s_ xs))
|
|
(s__ (fst s__ys))
|
|
(ys (snd s__ys)))
|
|
(tuple2 s__ (cons y ys))))))
|
|
|
|
;; mapAccumR :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
|
|
(define map-accum-r
|
|
(lambda (f s l)
|
|
(if (null? l)
|
|
(tuple2 s nil)
|
|
(let* ((x (head l))
|
|
(xs (tail l))
|
|
(s_ys (map-accum-r f s xs))
|
|
(s_ (fst s_ys))
|
|
(ys (snd s_ys))
|
|
(s__y (f s_ x))
|
|
(s__ (fst s__y))
|
|
(y (snd s__y)))
|
|
(tuple2 s__ (cons y ys))))))
|
|
|
|
;; maximum :: (Ord a) => [a] -> a
|
|
(define maximum
|
|
(lambda (l)
|
|
(foldl1 max2 l)))
|
|
|
|
;; minimum :: (Ord a) => [a] -> a
|
|
(define minimum
|
|
(lambda (l)
|
|
(foldl1 min2 l)))
|
|
|
|
;; nub :: (Eq a) => [a] -> [a]
|
|
(define nub
|
|
(lambda (l)
|
|
(nub-by equal? l)))
|
|
|
|
;; nubBy :: (a -> a -> Bool) -> [a] -> [a]
|
|
(define nub-by
|
|
(lambda (f l)
|
|
(if (null? l)
|
|
nil
|
|
(let ((x (head l))
|
|
(xs (tail l)))
|
|
(cons x (nub-by f (filter (lambda (y) (not (f x y))) xs)))))))
|
|
|
|
;; nil :: [a]
|
|
(define nil
|
|
(list))
|
|
|
|
;; notElem :: (Eq a) => a -> [a] -> Bool
|
|
(define not-elem
|
|
(lambda (x l)
|
|
(all (lambda (y) (not (equal? x y))) l)))
|
|
|
|
;; null :: [a] -> Bool
|
|
#;(define null?
|
|
(lambda (x)
|
|
(equal? x nil)))
|
|
|
|
;; or :: [Bool] -> Bool
|
|
(define any-true
|
|
(lambda (l)
|
|
(if (null? l)
|
|
#f
|
|
(or (head l) (any-true (tail l))))))
|
|
|
|
;; partition :: (a -> Bool) -> [a] -> ([a], [a])
|
|
(define partition*
|
|
(let ((select (lambda (p)
|
|
(lambda (x tf)
|
|
(let ((t (fst tf))
|
|
(f (snd tf)))
|
|
(if (p x)
|
|
(tuple2 (cons x t) f)
|
|
(tuple2 t (cons x f))))))))
|
|
(lambda (p xs)
|
|
(foldr (select p) (tuple2 nil nil) xs))))
|
|
|
|
;; product :: (Num a) => [a] -> a
|
|
(define product
|
|
(lambda (l)
|
|
(foldl * 1 l)))
|
|
|
|
;; replicate :: Int -> a -> [a]
|
|
(define replicate
|
|
(lambda (n x)
|
|
(if (= n 0)
|
|
nil
|
|
(cons x (replicate (- n 1) x)))))
|
|
|
|
;; reverse :: [a] -> [a]
|
|
#;(define reverse
|
|
(lambda (l)
|
|
(foldl (flip cons) nil l)))
|
|
|
|
;; scanl :: (a -> b -> a) -> a -> [b] -> [a]
|
|
(define scanl
|
|
(lambda (f q l)
|
|
(cons q (if (null? l)
|
|
nil
|
|
(scanl f (f q (head l)) (tail l))))))
|
|
|
|
;; scanl1 :: (a -> a -> a) -> [a] -> [a]
|
|
(define scanl1
|
|
(lambda (f l)
|
|
(if (null? l)
|
|
nil
|
|
(scanl f (head l) (tail l)))))
|
|
|
|
;; scanr :: (a -> b -> b) -> b -> [a] -> [b]
|
|
(define scanr
|
|
(lambda (f q0 l)
|
|
(if (null? l)
|
|
(list1 q0)
|
|
(let ((qs (scanr f q0 (tail l))))
|
|
(cons (f (head l) (head qs)) qs)))))
|
|
|
|
;; scanr1 :: (a -> a -> a) -> [a] -> [a]
|
|
(define scanr1
|
|
(lambda (f l)
|
|
(if (null? l)
|
|
nil
|
|
(if (null? (tail l))
|
|
l
|
|
(let ((qs (scanr1 f (tail l))))
|
|
(cons (f (head l) (head qs)) qs))))))
|
|
|
|
;; sort :: (Ord a) => [a] -> [a]
|
|
(define sort
|
|
(lambda (l)
|
|
(sort-by compare l)))
|
|
|
|
;; sortBy :: (a -> a -> Ordering) -> [a] -> [a]
|
|
(define sort-by
|
|
(lambda (f l)
|
|
(mergesort f l)))
|
|
|
|
;; mergesort :: (a -> a -> Ordering) -> [a] -> [a]
|
|
(define mergesort
|
|
(lambda (f l)
|
|
(mergesort* f (map1 list1 l))))
|
|
|
|
;; mergesort' :: (a -> a -> Ordering) -> [[a]] -> [a]
|
|
(define mergesort*
|
|
(lambda (f l)
|
|
(cond ((null? l) nil)
|
|
((null? (tail l)) (head l))
|
|
(else (mergesort* f (merge-pairs f l))))))
|
|
|
|
;; merge_pairs :: (a -> a -> Ordering) -> [[a]] -> [[a]]
|
|
(define merge-pairs
|
|
(lambda (f l)
|
|
(cond ((null? l) nil)
|
|
((null? (tail l)) l)
|
|
(else (cons (merge f (head l) (head (tail l)))
|
|
(merge-pairs f (tail (tail l))))))))
|
|
|
|
;; merge :: (a -> a -> Ordering) -> [a] -> [a] -> [a]
|
|
(define merge
|
|
(lambda (f l r)
|
|
(cond ((null? l) r)
|
|
((null? r) l)
|
|
(else (if (equal? (f (head l) (head r)) 'gt)
|
|
(cons (head r) (merge f l (tail r)))
|
|
(cons (head l) (merge f (tail l) r)))))))
|
|
|
|
;; span :: (a -> Bool) -> [a] -> ([a],[a])
|
|
(define span
|
|
(lambda (p l)
|
|
(if (null? l)
|
|
(tuple2 nil nil)
|
|
(if (p (head l))
|
|
(let ((r (span p (tail l))))
|
|
(tuple2 (cons (head l) (fst r)) (snd r)))
|
|
(tuple2 nil l)))))
|
|
|
|
;; splitAt :: Int -> [a] -> ([a],[a])
|
|
(define split-at
|
|
(lambda (n l)
|
|
(tuple2 (take n l) (drop n l))))
|
|
|
|
;; sum :: (Num a) => [a] -> a
|
|
(define sum
|
|
(lambda (l)
|
|
(foldl + 0 l)))
|
|
|
|
;; tail :: [a] -> [a]
|
|
(define tail cdr)
|
|
|
|
;; take :: Int -> [a] -> [a]
|
|
(define take
|
|
(lambda (n l)
|
|
(cond ((<= n 0) nil)
|
|
((null? l) nil)
|
|
(else (cons (head l) (take (- n 1) (tail l)))))))
|
|
|
|
;; takeWhile :: (a -> Bool) -> [a] -> [a]
|
|
(define take-while
|
|
(lambda (p l)
|
|
(if (null? l)
|
|
nil
|
|
(if (p (head l))
|
|
(cons (head l) (take-while p (tail l)))
|
|
nil))))
|
|
|
|
;; transpose :: [[a]] -> [[a]]
|
|
(define transpose
|
|
(lambda (l)
|
|
(let ((protect
|
|
(lambda (f)
|
|
(lambda (x)
|
|
(if (null? x)
|
|
nil
|
|
(f x))))))
|
|
(cond ((null? l) nil)
|
|
((null? (head l)) (transpose (tail l)))
|
|
(else (let* ((e (head l))
|
|
(x (head e))
|
|
(xs (tail e))
|
|
(xss (tail l)))
|
|
(cons (cons x
|
|
(filter (compose not null?)
|
|
(map1 (protect head) xss)))
|
|
(transpose (cons xs
|
|
(map1 (protect tail) xss))))))))))
|
|
|
|
;; unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
|
|
(define unfoldr
|
|
(lambda (f x)
|
|
(let ((r (f x)))
|
|
(if r
|
|
(cons (fst r) (unfoldr f (snd r)))
|
|
nil))))
|
|
|
|
;; (unfoldr (lambda (b) (if (= b 0) #f (tuple2 b (- b 1)))) 10)
|
|
;; => (10 9 8 7 6 5 4 3 2 1)
|
|
|
|
;; union :: (Eq a) => [a] -> [a] -> [a]
|
|
(define union
|
|
(lambda (a b)
|
|
(union-by equal? a b)))
|
|
|
|
;; unionBy :: (a -> a -> Bool) -> [a] -> [a] -> [a]
|
|
(define union-by
|
|
(lambda (f xs ys)
|
|
(let ((g (lambda (x y) (delete-by f y x))))
|
|
(append2 xs (foldl g (nub-by f ys) xs)))))
|
|
|
|
;; zip :: [a] -> [b] -> [(a, b)]
|
|
(define zip
|
|
(lambda (a b)
|
|
(zip-with tuple2 a b)))
|
|
|
|
;; zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
|
|
(define zip-with
|
|
(lambda (f a b)
|
|
(cond ((null? a) nil)
|
|
((null? b) nil)
|
|
(else (cons (f (head a) (head b))
|
|
(zip-with f (tail a) (tail b)))))))
|
|
|
|
;; zipWith3 :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
|
|
(define zip-with3
|
|
(lambda (f a b c)
|
|
(cond ((null? a) nil)
|
|
((null? b) nil)
|
|
((null? c) nil)
|
|
(else (cons (f (head a) (head b) (head c))
|
|
(zip-with3 f (tail a) (tail b) (tail c)))))))
|
|
|
|
|
|
|
|
;; control/monad.scm ;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;; replicateM :: (Monad m) => Int -> m a -> m [a]
|
|
(define-syntax replicate-m
|
|
(syntax-rules ()
|
|
((_ i x)
|
|
(replicate-m* i (lambda () x)))))
|
|
|
|
;; int -> (() -> a) -> [a]
|
|
(define replicate-m*
|
|
(lambda (i x)
|
|
(if (<= i 0)
|
|
nil
|
|
(cons (x) (replicate-m* (- i 1) x)))))
|
|
|
|
|
|
;; data/tree.scm ;;;;;;;;;;;;;;
|
|
|
|
;; Tree a -> [a]
|
|
(define flatten
|
|
(letrec ((f (lambda (t r)
|
|
(cond ((null? t) r)
|
|
((pair? t) (f (head t) (f (tail t) r)))
|
|
(else (cons t r))))))
|
|
(lambda (t)
|
|
(f t nil))))
|
|
|
|
;; Tree a -> [[a]]
|
|
(define levels
|
|
(lambda (t)
|
|
(if (null? t)
|
|
nil
|
|
(let ((lr (partition* (compose not pair?) t)))
|
|
(cons (fst lr) (levels (concat (snd lr))))))))
|
|
|
|
|
|
|
|
(module+ test
|
|
(require rackunit)
|
|
(check-equal? (drop 2 '(1 2 3 4 5 6)) '(3 4 5 6))
|
|
(check-equal? (transpose '((1 2) (3 4))) '((1 3) (2 4)))
|
|
)
|
|
|