Monads/Maybe monad: Difference between revisions

Rename Perl 6 -> Raku, alphabetize, minor clean-up
(Realize in F#)
(Rename Perl 6 -> Raku, alphabetize, minor clean-up)
Line 11:
 
A Maybe Monad is a monad which specifically encapsulates the type of an undefined value.
 
 
=={{header|ALGOL 68}}==
Line 398 ⟶ 397:
Index out of range
</pre>
 
=={{header|Factor}}==
Factor comes with an implementation of Haskell-style monads in the <code>monads</code> vocabulary.
Line 869:
</lang>
 
=={{header|Perl 6Phix}}==
{{trans|Julia}}
Phix has an "object" type which can be an integer or a string, so not entirely un-like Perl.<br>
Here we simply treat all strings or rather non-integers as the "unknown" type.
<lang Phix>function bind(object m, integer f)
return f(m)
end function
function unit(object m)
return m
end function
function times_five(object l)
return iff(integer(l)?l*5:l)
end function
function plus_four(object l)
return iff(integer(l)?l+4:l)
end function
 
procedure test(object l)
printf(1,"%v -> %v\n", {l, bind(bind(l,times_five),plus_four)})
end procedure
test(3)
test("none")</lang>
{{out}}
<pre>
3 -> 19
"none" -> "none"
</pre>
 
=={{header|Racket}}==
 
It is idiomatic in Racket to use <code>#f</code> for <code>Nothing</code>, and every other value is considered implicitly tagged with <code>Just</code>.
 
<lang racket>#lang racket
 
(require syntax/parse/define)
 
(define (bind x f) (and x (f x)))
(define return identity)
 
;; error when arg = 0
(define reciprocal (curry / 1))
;; error when arg < 0
(define (root x) (if (< x 0) (error 'bad) (sqrt x)))
;; error whe arg <= 0
(define (ln x) (if (<= x 0) (error 'bad) (log x)))
 
(define (lift f check) (λ (x) (and (check x) (f x))))
 
(define safe-reciprocal (lift reciprocal (negate (curry equal? 0))))
(define safe-root (lift root (curry <= 0)))
(define safe-ln (lift ln (curry < 0)))
 
(define (safe-log-root-reciprocal x)
(bind (bind (bind x safe-reciprocal) safe-root) safe-ln))
 
(define tests `(-2 -1 -0.5 0 1 ,(exp -1) 1 2 ,(exp 1) 3 4 5))
 
(map safe-log-root-reciprocal tests)
 
(define-syntax-parser do-macro
[(_ [x {~datum <-} y] . the-rest) #'(bind y (λ (x) (do-macro . the-rest)))]
[(_ e) #'e])
 
(define (safe-log-root-reciprocal* x)
(do-macro [x <- (safe-reciprocal x)]
[x <- (safe-root x)]
[x <- (safe-ln x)]
(return x)))
 
(map safe-log-root-reciprocal* tests)</lang>
 
{{out}}
<pre>
'(#f #f #f #f 0 0.5 0 -0.3465735902799726 -0.5 -0.5493061443340549 -0.6931471805599453 -0.8047189562170503)
'(#f #f #f #f 0 0.5 0 -0.3465735902799726 -0.5 -0.5493061443340549 -0.6931471805599453 -0.8047189562170503)
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2019.11}}
It is exceptionally difficult to come up with a compelling valuable use for
Line 963 ⟶ 1,044:
WAT Nothing Nothing Nothing Nothing
4.285714 0.233333 2.0701966780270626 1.455287232606842 -0.727643616303421</pre>
 
=={{header|Phix}}==
{{trans|Julia}}
Phix has an "object" type which can be an integer or a string, so not entirely un-like Perl.<br>
Here we simply treat all strings or rather non-integers as the "unknown" type.
<lang Phix>function bind(object m, integer f)
return f(m)
end function
function unit(object m)
return m
end function
function times_five(object l)
return iff(integer(l)?l*5:l)
end function
function plus_four(object l)
return iff(integer(l)?l+4:l)
end function
 
procedure test(object l)
printf(1,"%v -> %v\n", {l, bind(bind(l,times_five),plus_four)})
end procedure
test(3)
test("none")</lang>
{{out}}
<pre>
3 -> 19
"none" -> "none"
</pre>
 
=={{header|Racket}}==
 
It is idiomatic in Racket to use <code>#f</code> for <code>Nothing</code>, and every other value is considered implicitly tagged with <code>Just</code>.
 
<lang racket>#lang racket
 
(require syntax/parse/define)
 
(define (bind x f) (and x (f x)))
(define return identity)
 
;; error when arg = 0
(define reciprocal (curry / 1))
;; error when arg < 0
(define (root x) (if (< x 0) (error 'bad) (sqrt x)))
;; error whe arg <= 0
(define (ln x) (if (<= x 0) (error 'bad) (log x)))
 
(define (lift f check) (λ (x) (and (check x) (f x))))
 
(define safe-reciprocal (lift reciprocal (negate (curry equal? 0))))
(define safe-root (lift root (curry <= 0)))
(define safe-ln (lift ln (curry < 0)))
 
(define (safe-log-root-reciprocal x)
(bind (bind (bind x safe-reciprocal) safe-root) safe-ln))
 
(define tests `(-2 -1 -0.5 0 1 ,(exp -1) 1 2 ,(exp 1) 3 4 5))
 
(map safe-log-root-reciprocal tests)
 
(define-syntax-parser do-macro
[(_ [x {~datum <-} y] . the-rest) #'(bind y (λ (x) (do-macro . the-rest)))]
[(_ e) #'e])
 
(define (safe-log-root-reciprocal* x)
(do-macro [x <- (safe-reciprocal x)]
[x <- (safe-root x)]
[x <- (safe-ln x)]
(return x)))
 
(map safe-log-root-reciprocal* tests)</lang>
 
{{out}}
<pre>
'(#f #f #f #f 0 0.5 0 -0.3465735902799726 -0.5 -0.5493061443340549 -0.6931471805599453 -0.8047189562170503)
'(#f #f #f #f 0 0.5 0 -0.3465735902799726 -0.5 -0.5493061443340549 -0.6931471805599453 -0.8047189562170503)
</pre>
 
=={{header|Ruby}}==
10,333

edits