Skip to content

@RayRacine /try.rkt secret

Embed URL


Subversion checkout URL

You can clone with
Download ZIP
#lang typed/racket/base
(struct-out Failure)
(struct-out Success)
failed succeded get invert
try-map try-flatmap try-foreach try-filter try-exists
rescue recover
try continue with-try)
(struct: (T) Failure ([exception : exn]))
(struct: (T) Success ([result : T]))
(define-type (Try T) (U (Failure T) (Success T)))
(: failed (All (T) (Try T) -> Boolean))
(define (failed try)
(Failure? try))
(: succeded (All (T) (Try T) -> Boolean))
(define (succeded try)
(Success? try))
(: get (All (T) (Try T) -> T))
(define (get try)
((Failure? try) (raise (Failure-exception try)))
((Success? try) (Success-result try))))
;; Is a generic "lens" library on structures possible??
;; Higher kinded types, L is a type constructor binding for M (Success) and N (Failure)
;; (: S-map (All (L T U) (L T) (T -> U) -> (L U)))
(: try-map (All (T U) (Try T) (T -> U) -> (Try U)))
(define (try-map try fn)
((Success? try)
(Success (fn (Success-result try))))
((Failure? try) try)))
(: try-flatmap (All (T U) (Try T) (T -> (Try U)) -> (Try U)))
(define (try-flatmap try fn)
((Success? try)
(with-handlers ([exn:fail? (λ: ((ex : exn))
(Failure ex))])
(fn (Success-result try))))
((Failure? try) try)))
(: try-foreach (All (T U) (Try T) (T -> U) -> Void))
(define (try-foreach try fn)
((Success? try)
(fn (Success-result try))
((Failure? try)
(: try-filter (All (T) (Try T) (T -> Boolean) -> (Try T)))
(define (try-filter try select?)
((Success? try) ;; need to see of Racket has strutural pattern matching kindof cond!!!
(if (select? (Success-result try))
(Failure (exn:fail (format "Unsatisfied try filter predicate for ~s" (Success-result try))
((Failure? try)
(: try-exists (All (T) (Try T) (T -> Boolean) -> Boolean))
(define (try-exists try exists?)
((Success? try)
(exists? (Success-result try)))
((Failure? try) #f)))
(: invert ((Try exn) -> (Try exn)))
(define (invert try)
((Success? try)
(Failure (exn:fail (format "Inverted try. Success for ~s is Failure" (Success-result try))
((Failure? try)
(Success (Failure-exception try)))))
(: continue (All (T V W) (Try T) (T -> (Try V)) (exn -> (Try W)) -> (Try (U V W))))
(define (continue try on-success on-failure)
((Success? try)
(on-success (Success-result try)))
((Failure? try)
(on-failure (Failure-exception try)))))
;; Rescue a failed computation if the rescue function is capable of doing so.
;; Careful of side effects by the rescue function.
;; Should my-hero be a PartialFunction as opposed to one which returns Option.
(: rescue (All (T) (Try T) ((Failure T) -> (Option (Try T))) -> (Try T)))
(define (rescue try my-hero)
(with-handlers ([exn:fail? (λ (ex)
(Failure ex))])
((Failure? try)
(let ((result (my-hero try)))
(if result
((Success? try) try))))
(: recover (All (T) (Try T) ((Failure T) -> (Option T)) -> (Try T)))
(define (recover try my-heroine)
(with-handlers ([exn:fail? (λ (ex)
(Failure ex))])
((Failure? try)
(let ((result (my-heroine try)))
(if result
(Success result)
((Success? try) try))))
(: try (All (T) (-> T) -> (Try T)))
(define (try thunk)
(with-handlers ([exn:fail? (lambda (ex)
(Failure ex))])
(Success (thunk))))
(define-syntax with-try
(syntax-rules ()
((_ body ...)
(try (lambda () body ...)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.