Skip to content

LLazarek/simple-option

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

simple-option

Simple scheme-y implementations of option and either datatypes. See the docs for details.

Installation

raco pkg install https://github.com/LLazarek/simple-option

Documentation

raco docs simple-option

Examples

option

 (require simple-option)

 ;; Without any absences, option-let* is just like match-let*
 (option-let* ([x 1]
		[(list y) '(2)])
	       (+ x y))
 ; => 3

 ;; Absences short-circuit the whole expression to absent
 (option-let* ([x absent]
		; the rest is skipped
		[(list y) '(2)])
	       (+ x y))
 ; => absent


 (define (fails-on-odd-numbers n)
   (if (even? n)
	(/ n 2)
	absent))
 (option-let* ([x 1]
		[y (fails-on-odd-numbers 8)]
		[z (fails-on-odd-numbers y)])
	       (+ x y z))
 ; => 7

 (option-let* ([x 1]
		[y (fails-on-odd-numbers 7)]
		; the rest is skipped
		[z (fails-on-odd-numbers y)])
	       (+ x y z))
 ; => absent


 ;; fail-if is mostly useful in option-let*, to explicitly short-circuit under a condition

 ;; the remaining examples presented as tests...
 (test-equal? (option-let* ([x 5]
			     [y (fail-if (odd? x))]
			     [z (/ x 2)])
			    (add1 z))
	       absent)
 (test-equal? (option-let* ([x 8]
			     [y (fail-if (odd? x))]
			     [z (/ x 2)])
			    (add1 z))
	       5)

 (test-equal? (for/list ([x (in-option 5)]) x)
	       '(5))
 (test-equal? (for/list ([x (in-option absent)]) x)
	       '())

 (test-equal? (for/first/option ([i '(3 5 7)]
				  #:when (even? i))
		 i)
	       absent)
 (test-equal? (for/first/option ([i '(3 5 2 7)]
				  #:when (even? i))
		 i)
	       2)

either

(require simple-option/either)

(test-equal? (either-let* () 5) 5)
(test-equal? (either-let* ([x 5])
			    x)
	       5)
(test-equal? (either-let* ([x (failure "bad")])
			    x)
	       (failure "bad"))
(test-equal? (either-let* ([x 5]
			     [y (failure "bad")])
			    (+ x y))
	       (failure "bad"))
(test-equal? (either-let* ([x 5]
			     [y (+ x 5)])
			    (+ x y))
	       15)


(test-equal? (either-let* ([x 5]
			     [y (fail-if (odd? x) "bad x")])
			    (/ x 2))
	       (failure "bad x"))
(test-equal? (either-let* ([x 10]
			     [y (fail-if (odd? x) "bad x")])
			    (/ x 2))
	       5)

(test-equal? (for/list ([x (in-success 5)])
		 x)
	       '(5))
(test-equal? (for/list ([x (in-success (failure "bad"))])
		 x)
	       '())

(test-equal? (for/list ([x (in-failure 5)])
		 x)
	       '())
(test-equal? (for/list ([m (in-failure (failure "bad"))])
		 m)
	       '("bad"))

(test-equal? (for/first/either ([i '(3 5 7)]
				  #:when (even? i))
		 #:failure-message "no evens!"
		 i)
	       (failure "no evens!"))
(test-equal? (for/first/either ([i '(3 5 2 7)]
				  #:when (even? i))
		 #:failure-message "no evens!"
		 i)
	       2)

(test-equal? (hash-ref/either (hash) 'a)
	       (failure "hash-ref/either: key 'a not found"))
(test-equal? (hash-ref/either (hash) 'a "bad")
	       (failure "bad"))
(test-equal? (hash-ref/either (hash 'a 5) 'a)
	       5)

(test-equal? (first/either empty)
	       (failure "first/either: empty list"))
(test-equal? (first/either empty "bad")
	       (failure "bad"))
(test-equal? (first/either '(5))
	       5)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages