Monads/Maybe monad: Difference between revisions

Added FreeBASIC
(Added FreeBASIC)
 
(27 intermediate revisions by 10 users not shown)
Line 14:
=={{header|ALGOL 68}}==
{{trans|JavaScript}}
<langsyntaxhighlight lang="algol68">BEGIN
 
# This is a translation of the Javascript sample, main differences are because Algol 68 #
Line 139:
print( ( "]", newline ) )
END</langsyntaxhighlight>
{{out}}
<pre>
Line 159:
 
 
<langsyntaxhighlight AppleScriptlang="applescript">property e : 2.71828182846
 
on run {}
Line 297:
return lst
end map
</syntaxhighlight>
</lang>
 
{{Out}}
Line 305:
 
{missing value, missing value, missing value, missing value, 0.5, 0.0, -0.346573590279, -0.499999999999, -0.549306144333, -0.69314718056, -0.804718956217}</pre>
 
=={{header|ATS}}==
<syntaxhighlight lang="ats">
#include "share/atspre_staload.hats"
 
(* There are "Option" and "Option_vt" in the ATS2 prelude, but I shall
construct something anew. *)
 
datatype Maybe (a : t@ype+) =
| Nothing of ()
| Just of a
 
fn {a, b : t@ype}
bind_Maybe {u : bool}
(m : Maybe a,
f : a -<cloref1> Maybe b) : Maybe b =
case+ m of
| Nothing {a} () => Nothing {b} ()
| Just {a} x => f x
 
infixl 0 >>=
overload >>= with bind_Maybe
 
implement
main0 () =
let
val f : int -<cloref1> Maybe int =
lam i =<cloref1> if (i : int) < 0 then Nothing () else Just i
val g : int -<cloref1> Maybe string =
lam i =<cloref1> Just (tostring_val<int> i)
in
case+ Just 123 >>= f >>= g of
| Nothing () => println! ("Nothing ()")
| Just s => println! ("Just (\"", s : string, "\")");
case+ Just ~123 >>= f >>= g of
| Nothing () => println! ("Nothing ()")
| Just s => println! ("Just (\"", s : string, "\")")
end
</syntaxhighlight>
 
{{out}}
<pre>$ patscc -std=gnu2x -g -O2 -DATS_MEMALLOC_GCBDW maybe_monad_ats.dats -lgc && ./a.out
Just ("123")
Nothing ()</pre>
 
=={{header|C}}==
<syntaxhighlight lang="c">
<lang C>
#include <stdio.h>
#include <stdlib.h>
Line 333 ⟶ 377:
else if (m->t == STRING)
printf("Just \"%s\" : STRING\n", m->s);
 
else
printf("Nothing\n");
 
}
 
Line 428 ⟶ 476:
print_Maybe(bind_maybe(bind_maybe(m_1, f_1), f_2)); // (m_1 `bind` f_1) `bind` f_2 :: Maybe String -- it prints 49 'x' characters in a row
}
</syntaxhighlight>
</lang C>
{{out}}
<pre>
Just 7 : INT
Just "lorem ipsum dolor sit amet" : STRING
Just 49 : INT
Just "xxxxxxx" : STRING
Just "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" : STRING
</pre>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <cmath>
#include <optional>
Line 507 ⟶ 563:
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 519 ⟶ 575:
2.5 -> 1.159279, nothing
</pre>
 
=={{header|C sharp|C#}}==
 
<syntaxhighlight lang="csharp">using System;
 
namespace RosettaMaybe
{
// courtesy of https://www.dotnetcurry.com/patterns-practices/1510/maybe-monad-csharp
public abstract class Maybe<T>
{
public sealed class Some : Maybe<T>
{
public Some(T value) => Value = value;
public T Value { get; }
}
public sealed class None : Maybe<T> { }
}
 
class Program
{
static Maybe<double> MonadicSquareRoot(double x)
{
if (x >= 0)
{
return new Maybe<double>.Some(Math.Sqrt(x));
}
else
{
return new Maybe<double>.None();
}
}
static void Main(string[] args)
{
foreach (double x in new double[] { 4.0D, 8.0D, -15.0D, 16.23D, -42 })
{
Maybe<double> maybe = MonadicSquareRoot(x);
if (maybe is Maybe<double>.Some some)
{
Console.WriteLine($"The square root of {x} is " + some.Value);
}
else
{
Console.WriteLine($"Square root of {x} is undefined.");
}
}
}
}
}</syntaxhighlight>
 
 
=={{header|Clojure}}==
 
<langsyntaxhighlight lang="clojure">
(defn bind [val f]
(if-let [v (:value val)] (f v) val))
Line 535 ⟶ 640:
(bind (bind (unit 8) opt_add_3) opt_str) ; evaluates to {:value "11"}
(bind (bind (unit nil) opt_add_3) opt_str) ; evaluates to {:value nil}
</syntaxhighlight>
</lang>
 
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{Trans|Go}}
<syntaxhighlight lang="delphi">
<lang Delphi>
program Maybe_monad;
 
Line 614 ⟶ 719:
end;
Readln;
end.</langsyntaxhighlight>
{{out}}
<pre> 3 -> 6
Line 625 ⟶ 730:
Functions which return something not in Maybe.domain are unsafe and return (#f . input-value), If a function is given as input a (#f . value) element, it will return this element.
 
<langsyntaxhighlight lang="scheme">
(define (Maybe.domain? x) (or (number? x) (string? x)))
(define (Maybe.unit elem (bool #t)) (cons bool elem))
Line 664 ⟶ 769:
(->> 1 Maybe.unit (Maybe.bind u-log) (Maybe.bind u-inv) (Maybe.bind number->string) Maybe.print)
→ ❌ (#f . 0)
</syntaxhighlight>
</lang>
 
=={{header|FreeBASIC}}==
{{trans|Wren}}
<syntaxhighlight lang="vbnet">Type mmaybe
As Integer value
End Type
 
Function Bindf(m As mmaybe, f As Function(As mmaybe) As mmaybe) As mmaybe
Return f(m)
End Function
 
Function Unit(i As Integer) As mmaybe
Dim As mmaybe m
m.value = i
Return m
End Function
 
Function Decrement(mm As mmaybe) As mmaybe
Dim As mmaybe result
result.value = Iif(mm.value = 0, 0, mm.value - 1)
Return Unit(result.value)
End Function
 
Function Triple(mm As mmaybe) As mmaybe
Dim As mmaybe result
result.value = Iif(mm.value = 0, 0, 3 * mm.value)
Return Unit(result.value)
End Function
 
Dim As Integer values(3) = {3, 4, 0, 5}
Dim As Function(As mmaybe) As mmaybe Ptr decrementPtr = @Decrement
Dim As Function(As mmaybe) As mmaybe Ptr triplePtr = @Triple
 
For i As Integer = Lbound(values) To Ubound(values)
Dim As mmaybe m1 = Unit(values(i))
Dim As mmaybe m2 = Bindf(Bindf(m1, decrementPtr), triplePtr)
Dim As String s1 = Iif(m1.value = 0, "none", Str(m1.value))
Dim As String s2 = Iif(m2.value = 0, "none", Str(m2.value))
Print Using "\ \ -> \ \"; s1; s2
Next i
 
Sleep</syntaxhighlight>
{{out}}
<pre> 3 -> 6
4 -> 9
none -> none
5 -> 12</pre>
 
=={{header|F_Sharp|F#}}==
<langsyntaxhighlight lang="fsharp">
// We can use Some as return, Option.bind and the pipeline operator in order to have a very concise code
 
Line 676 ⟶ 828:
f1 4 |> Option.bind f2 |> printfn "Value is %A" // bind when option (maybe) has data
None |> Option.bind f2 |> printfn "Value is %A" // bind when option (maybe) does not have data
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 685 ⟶ 837:
=={{header|Factor}}==
Factor comes with an implementation of Haskell-style monads in the <code>monads</code> vocabulary.
<langsyntaxhighlight lang="factor">USING: monads ;
FROM: monads => do ;
 
Line 694 ⟶ 846:
! Prints "nothing"
nothing >>= [ 2 * maybe-monad return ] swap call
>>= [ 1 + maybe-monad return ] swap call .</langsyntaxhighlight>
Or:
<langsyntaxhighlight lang="factor">3 <just> [ 2 * <just> ] bind [ 1 + <just> ] bind .
nothing [ 2 * <just> ] bind [ 1 + <just> ] bind .</langsyntaxhighlight>
Or with <code>do</code> notation:
<langsyntaxhighlight lang="factor">{
[ 3 <just> ]
[ 2 * <just> ]
Line 708 ⟶ 860:
[ 2 * <just> ]
[ 1 + <just> ]
} do .</langsyntaxhighlight>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 760 ⟶ 912:
fmt.Printf("%4s -> %s\n", s1, s2)
}
}</langsyntaxhighlight>
 
{{out}}
Line 773 ⟶ 925:
 
Haskell has the built-in <code>Monad</code> type class, and the built-in <code>Maybe</code> type already conforms to the <code>Monad</code> type class.
<langsyntaxhighlight lang="haskell">main = do print $ Just 3 >>= (return . (*2)) >>= (return . (+1)) -- prints "Just 7"
print $ Nothing >>= (return . (*2)) >>= (return . (+1)) -- prints "Nothing"</langsyntaxhighlight>
 
Or, written using <code>do</code> notation:
<langsyntaxhighlight lang="haskell">main = do print (do x <- Just 3
y <- return (x*2)
z <- return (y+1)
Line 784 ⟶ 936:
y <- return (x*2)
z <- return (y+1)
return z)</langsyntaxhighlight>
 
Or alternately:
<langsyntaxhighlight lang="haskell">main = do print (do x <- Just 3
let y = x*2
let z = y+1
Line 794 ⟶ 946:
let y = x*2
let z = y+1
return z)</langsyntaxhighlight>
 
Deriving and composing safe versions of reciprocal, square root and log functions. :
<langsyntaxhighlight lang="haskell">import Control.Monad ((>=>))
 
safeVersion :: (a -> b) -> (a -> Bool) -> a -> Maybe b
Line 809 ⟶ 961:
safeLogRootReciprocal = safeReciprocal >=> safeRoot >=> safeLog
 
main = print $ map safeLogRootReciprocal [-2, -1, -0.5, 0, exp (-1), 1, 2, exp 1, 3, 4, 5]</langsyntaxhighlight>
{{out}}
<pre>[Nothing,Nothing,Nothing,Nothing,Just 0.5,Just 0.0,Just (-0.3465735902799726),Just (-0.5),Just (-0.5493061443340549),Just (-0.6931471805599453),Just (-0.8047189562170503)]</pre>
 
=={{header|Hoon}}==
<langsyntaxhighlight lang="hoon">
:- %say
|= [^ [[txt=(unit ,@tas) ~] ~]]
Line 834 ⟶ 986:
(some (mul a 2))
--
</syntaxhighlight>
</lang>
 
Hoon has a built-in rune, %smsg (;~) that binds gates under a monad.
Line 857 ⟶ 1,009:
It's difficult to find a useful and illustrative (but simple) example of this task in J. So we shall not try to be useful.
 
<syntaxhighlight lang="j">
<lang J>
NB. monad implementation:
unit=: <
Line 884 ⟶ 1,036:
┌──┐
│_.│
└──┘</langsyntaxhighlight>
 
=={{header|Java}}==
Java has a built-in generic "Maybe" monad in form of the Optional<T> class.
 
The class has static methods, "of" and "ofNullable", which act as the unit function
for wrapping nullable and non-nullable values respectively.
 
The class instance method, "flatMap", acts as the bind function.
<syntaxhighlight lang="java">
import java.util.Optional;
 
public final class MonadMaybe {
 
public static void main(String[] aArgs) {
System.out.println(doubler(5).flatMap(MonadMaybe::stringify).get());
System.out.println(doubler(2).flatMap(MonadMaybe::stringifyNullable).get());
Optional<String> option = doubler(0).flatMap(MonadMaybe::stringifyNullable);
String result = option.isPresent() ? option.get() : "Result is Null";
System.out.println(result);
}
private static Optional<Integer> doubler(int aN) {
return Optional.of(2 * aN);
}
 
private static Optional<String> stringify(int aN) {
return Optional.of("A".repeat(aN));
}
 
private static Optional<String> stringifyNullable(int aN) {
return ( aN > 0 ) ? Optional.ofNullable("A".repeat(aN)) : Optional.ofNullable(null);
}
 
}
</syntaxhighlight>
{{ out }}
<pre>
AAAAAAAAAA
AAAA
Result is Null
</pre>
 
=={{header|JavaScript}}==
Line 892 ⟶ 1,089:
Example: deriving and composing safe versions of reciprocal, square root and log functions.
 
<langsyntaxhighlight JavaScriptlang="javascript">(function () {
'use strict';
 
Line 1,000 ⟶ 1,197:
);
 
})();</langsyntaxhighlight>
 
{{Out}}
Line 1,009 ⟶ 1,206:
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">struct maybe x::Union{Real, Missing}; end
 
Base.show(io::IO, m::maybe) = print(io, m.x)
Line 1,025 ⟶ 1,222:
 
println(b, " -> ", bind(f2, bind(f1, b)))
</langsyntaxhighlight>{{out}}
<pre>
3 -> 19
Line 1,037 ⟶ 1,234:
 
Rather than write something from scratch, we use this class to complete this task.
<langsyntaxhighlight lang="scala">// version 1.2.10
 
import java.util.Optional
Line 1,060 ⟶ 1,257:
/* prints 'false' as there is no value present in the Optional<String> instance */
println(getOptionalInt(0).flatMap(::getOptionalString2).isPresent)
}</langsyntaxhighlight>
 
{{out}}
Line 1,071 ⟶ 1,268:
=={{header|Lua}}==
{{works with|lua|5.3}}
<langsyntaxhighlight lang="lua">
-- None is represented by an empty table. Some is represented by any
-- array with one element. You SHOULD NOT compare maybe values with the
Line 1,152 ⟶ 1,349:
local outList = map(safeComputation, inList)
print("output:", table.concat(map(maybeToStr, outList), ", "), "\n")
</syntaxhighlight>
</lang>
 
 
=={{header|M2000 Interpreter}}==
Revision 1. Now the operator "=" check if we have same status on haveValue for the two objects. If not we get the false in compare. Also the unit() function return "none" object from a an object not "none".
 
M2000 create objects (of type Group) either from a Class (which is a function), or from a copy of an object. The life of an object depends of the storing site, and the use of a pointer or not. Here all objects are one of two kinds: Objects like none, m1, m2, m3 and m5 are destruct at the exit of the module. Object on the SetA like none and none.unit() (which is a copy of none), destruct when last pointer (here SetA) deleted, and for this example, because SetA is local variable, the delete happen at the exit of current module. The m object which used in Bind() and Unit() function, and the g object are all objects which life end at the exit of those function, although these functions return a pointer to a copy of the m object, and check an internal field which make it "float". A float object is something different from an object holding by a pointer. M2000 always "expand" a float object when we place it to a variable (as a copy, or if the variable hold another object - always as group else we get error 0 - as a merge of these). So when we pick a "float" object from array, we get a copy. M2000 can use pointer to groups. The second list show how we can use pointers to groups. Pointers can be one of two types: A real pointes (here we use real pointers), or a weak pointer. The -> operator in a ->m (or =pointer(m)) where m hold a group (not a pointer) return a weak pointer (invalid if actual variable not exist). Here we use ->(m) which make m a float group and then change it to a pointer to float group (same as =pointer((m))). A pointer(none) return a real pointer if none is a pointer to group, or a weak pointer if it isn't a pointer. A pointer to group is a group, not an address. A pointer() return the Null pointer (which is a group of type Null). The Null group (user object in M2000), has a type that cannot inherit to other classes, also in a group merge with null we don't merge Null type. Merging is another way to produce groups from two or more other types, using objects (not classes).
 
===== Without using pointers =====
 
<syntaxhighlight lang="m2000 interpreter">
Class maybe {
private:
variant [val]="none"
boolean haveValue
public:
property val {
value // val return the [val] value
}
function bind(f) {
m=This // we can read private because bind is function of same class as m
if m.haveValue Then m.[val]=f(m.[val])
=m // copy (not pointer)
}
Operator "=" (z as maybe) {
if z.havevalue xor .havevalue then
push false
else
Push z.[val]=.[val]
end if
}
Function unit() {
variant k
if match("G") then // so we can read maybe class
read g as maybe // fail if not maybe class
if g.havevalue then push g.val
end if
Read ? k
m=This
if not type$(k)="Empty" then
integer v=k ' fail if k can't convert to integer
m.[val]=v
m.haveValue=true
else // so now we can produce "none" from an object which isn't "none"
m.[val]="none"
m.haveValue=false
end if
=m // copy (not pointer)
}
class:
// after class: all are temporary for the constuction phase
// module with class name is the contructor
// the object constracted before enter this module
// but we can change it. So we return a new one.
module maybe {
// so the constructor is the same as the .unit
// ![] pick argument list and place to unit()
// optionally we can skip the call if we have empty argument list
if not empty then
this=.unit(![])
end if
}
}
none=maybe()
decrement =lambda (x as integer)->x-1%
triple =lambda (x as integer)->x*3%
variant emptyvariant
// 3 and 4 are double, 5 is integer type
SetA=(3,4,none,5%, emptyvariant, none.unit())
k=each(SetA)
While K
m1=none.unit(array(k)) // pick element k^
m2=m1.bind(decrement).bind(triple)
m3=maybe(m2)
Print m1.val+" -> "+m2.val, m3=m2, m3.val
End While
Try ok {
m5=maybe("Hello")
}
Print not ok // true , "Hello" not accepted
</syntaxhighlight>
 
 
===== Using pointers =====
 
 
<syntaxhighlight lang="m2000 interpreter">
Class maybe {
private:
variant [val]="none"
boolean haveValue
public:
property val {
value // val return the [val] value
}
function bind(f) {
m=This // we can read private because bind is function of same class as m
if m.haveValue Then m.[val]=f(m.[val])
->(m) // pointer
}
Operator "=" (z as maybe) {
if z.havevalue xor .havevalue then
push false
else
Push z.[val]=.[val]
end if
}
Function unit() {
variant k
if match("G") then // so we can read maybe class
read g as maybe // fail if not maybe class
if g.havevalue then push g.val
end if
Read ? k
m=This
if not type$(k)="Empty" then
integer v=k ' fail if k can't convert to integer
m.[val]=v
m.haveValue=true
else // so now we can produce "none" from an object which isn't "none"
m.[val]="none"
m.haveValue=false
end if
->(m) // pointer
}
class:
module maybe {
if not empty then
this=.unit(![])
end if
}
}
none->maybe()
decrement =lambda (x as integer)->x-1%
triple =lambda (x as integer)->x*3%
variant emptyvariant
SetA=(3,4,none,5%, emptyvariant, none=>unit())
k=each(SetA)
document doc$
While k
m1=none=>unit(array(k)) // pick element k^
m2=m1=>bind(decrement)=>bind(triple)
m3=maybe(m2)
doc$=m1=>val+" -> "+m2=>val+" m2=m3 -> "+if$(m2=m3->"True", "False")+{
}
End While
Try ok {
m5=maybe("Hello")
}
Doc$= (not ok)+{
} // true , "Hello" not accepted
report doc$
clipboard doc$
</syntaxhighlight>
{{out}}
<pre>
3 -> 6 True 6
4 -> 9 True 9
none -> none True none
5 -> 12 True 12
none -> none True none
none -> none True none
True
</pre>
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">import options,math,sugar,strformat
template checkAndWrap(x:float,body:typed): untyped =
if x.classify in {fcNormal,fcZero,fcNegZero}:
Line 1,178 ⟶ 1,539:
when isMainModule:
for i in [0.9,0.0,-0.9,3.0]:
echo some(i) --> reciprocal --> log --> format</langsyntaxhighlight>
{{out}}<pre>some("0.11")
none(string)
none(string)
some("-1.10")</pre>
 
=={{header|OCaml}}==
The Option module already has our bind and return operations. If we wanted to redefine them :
<syntaxhighlight lang="ocaml">let bind opt func = match opt with
| Some x -> func x
| None -> None
 
let return x = Some x</syntaxhighlight>
To easily manipulate bind, we can use infix operators and let pruning :
<syntaxhighlight lang="ocaml">let (-->) = bind
let (let*) = bind
 
let print_str_opt x =
Format.printf "%s" (Option.value ~default:"None" x)</syntaxhighlight>
Example:
<syntaxhighlight lang="ocaml">let safe_div x y = if y = 0.0 then None else return (x /. y)
let safe_root x = if x < 0.0 then None else return (sqrt x)
let safe_str x = return (Format.sprintf "%#f" x)
 
(* Version 1 : explicit calls *)
let () =
let v = bind (bind (safe_div 5. 3.) safe_root) safe_str in
print_str_opt v
 
(* Version 2 : with an operator *)
let () =
let v = safe_div 5. 3. --> safe_root --> safe_str in
print_str_opt v
 
(* Version 3 : let pruning really shine when inlining functions *)
let () =
let v =
let* x = safe_div 5. 3. in
let* y = if x < 0.0 then None else return (sqrt x) in
return (Format.sprintf "%#f" y)
in print_str_opt v</syntaxhighlight>
 
=={{header|Perl}}==
{{trans|Haskell}}
<langsyntaxhighlight Perllang="perl"># 20201101 added Perl programming solution
 
use strict;
Line 1,204 ⟶ 1,601:
->flat_map( \&safeLog );
$safeLogRootReciprocal->is_nothing ? "NaN" : $safeLogRootReciprocal->value;
} (-2, -1, -0.5, 0, exp (-1), 1, 2, exp(1), 3, 4, 5) ), "\n";</langsyntaxhighlight>
{{out}}
<pre>NaN NaN NaN NaN 0.5 0 -0.346573590279973 -0.5 -0.549306144334055 -0.693147180559945 -0.80471895621705</pre>
Line 1,212 ⟶ 1,609:
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.
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #008080;">function</span> <span style="color: #000000;">bindf</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">)</span>
Line 1,234 ⟶ 1,631:
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"none"</span><span style="color: #0000FF;">)</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 1,243 ⟶ 1,640:
=={{header|Python}}==
 
The <code>Maybe</code> class constructor is effectively the <code>unit</code> function. Note that I've used <code>>></code> as the bind operator. Trying to chain <code>__irshift__</code> (<code>>>=</code>) would be a syntax error.
In this implementation, a <code>Maybe</code> type's constructor is effectively
the <code>unit</code> function. Note that I've used <code>>></code> as the bind
operator. Trying to chain <code>__irshift__</code> (<code>>>=</code>) would be a
syntax error.
 
<syntaxhighlight lang="python">
<lang python>"""A Maybe Monad. Requires Python >= 3.7 for type hints."""
"""A Maybe monad. Requires Python >= 3.7 for type hints."""
from __future__ import annotations
 
from typing import Any
from typing import Callable
from typing import Generic
Line 1,260 ⟶ 1,654:
 
T = TypeVar("T")
U = TypeVar("U")
 
 
Line 1,269 ⟶ 1,664:
self.value = value
 
def __rshift__(self, func: Callable[[Optional[T]], Maybe[AnyU]]) -> Maybe[U]:
return self.bind(func)
 
def bind(self, func: Callable[[Optional[T]], Maybe[AnyU]]) -> Maybe[AnyU]:
return func(self.value)
 
Line 1,281 ⟶ 1,676:
def plus_one(value: Optional[int]) -> Maybe[int]:
if value is not None:
return Maybe[int](value + 1)
return Maybe[int](None)
 
 
def currency(value: Optional[int]) -> Maybe[str]:
if value is not None:
return Maybe[str](f"${value}.00")
return Maybe[str](None)
 
 
Line 1,295 ⟶ 1,690:
 
for case in test_cases:
m_intresult = Maybe[int](case) >> plus_one >> currency
 
result = m_int >> plus_one >> currency
# or..
# result = m_intMaybe(case).bind(plus_one).bind(currency)
 
print(f"{str(case):<4} -> {result}")
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,314 ⟶ 1,710:
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>.
 
<langsyntaxhighlight lang="racket">#lang racket
 
(require syntax/parse/define)
Line 1,351 ⟶ 1,747:
(return x)))
 
(map safe-log-root-reciprocal* tests)</langsyntaxhighlight>
 
{{out}}
Line 1,375 ⟶ 1,771:
below.
 
<syntaxhighlight lang="raku" perl6line>my $monad = <42>;
say 'Is $monad an Int?: ', $monad ~~ Int;
say 'Is $monad a Str?: ', $monad ~~ Str;
say 'Wait, what? What exactly is $monad?: ', $monad.^name;</langsyntaxhighlight>
{{out}}
<pre>Is $monad an Int?: True
Line 1,395 ⟶ 1,791:
candidate.
 
<syntaxhighlight lang="raku" perl6line># Build a Nothing type. When treated as a string it returns the string 'Nothing'.
# When treated as a Numeric, returns the value 'Nil'.
class NOTHING {
Line 1,438 ⟶ 1,834:
# all; but Ethiopic number 30, times vulgar fraction 1/7, is.
put ($_, .&recip, .&root, .&ln, .&(&ln o &root o &recip) )».&center
for -2, -1, -0.5, 0, exp(-1), 1, 2, exp(1), 3, 4, 5, 'WAT', ፴ × ⅐;</langsyntaxhighlight>
{{out}}
<pre> "Number" Reciprocal Square root Natural log Composed
Line 1,457 ⟶ 1,853:
=={{header|REXX}}==
This REXX version is modeled after the Zkl version.
<langsyntaxhighlight lang="rexx">/*REXX program mimics a bind operation when trying to perform addition upon arguments. */
call add 1, 2
call add 1, 2.0
Line 1,480 ⟶ 1,876:
end /*k*/
say 'sum=' $
return $</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
Line 1,500 ⟶ 1,896:
OOP version using Ruby's block syntax
 
<langsyntaxhighlight lang="ruby">class Maybe
def initialize(value)
@value = value
Line 1,548 ⟶ 1,944:
Maybe.unit(nil).bind { |n| Maybe.unit(2*n) }.bind { |n| Maybe.unit(n+1) }
#=> #<Maybe @value=nil>
</syntaxhighlight>
</lang>
 
=={{header|Rust}}==
The <code>Maybe</code> monad is called <code>Option<T></code> in Rust, it's widely used in the standard library and user code for functions that might not have sensible return values in certain cases but it's not an error/failure, such as a key doesn't exist for a hash map.
 
In addition, pure/just/return is <code>Some(T)</code> and bind is <code>Option::<T>::and_then(self, F)</code>.
 
<syntaxhighlight lang="Rust">
use std::collections::HashMap;
 
/// Returns the arithmetic square root of x, if it exists
fn arithmetic_square_root(x: u8) -> Option<u8> {
// the number of perfect squares for u8 is so low you can just fit the entire list in memory
let perfect_squares: HashMap<u8, u8> = HashMap::from([
(0, 0),
(1, 1),
(4, 2),
(9, 3),
(16, 4),
(25, 5),
(36, 6),
(49, 7),
(64, 8),
(81, 9),
(100, 10),
(121, 11),
(144, 12),
(169, 13),
(196, 14),
(225, 15),
]);
 
// `HashMap::<K, V>::get(&self, &Q)` also returns a `Option<&V>`, we then turn it to `Option<V>`
perfect_squares.get(&x).copied()
}
 
 
/// If x in base 10 is also a valid number when looking upside down, return a string slice for that
/// number upside down
fn upside_down_num(x: u8) -> Option<&'static str> {
match x {
0 => Some("0"),
1 => Some("1"),
6 => Some("9"),
8 => Some("8"),
9 => Some("6"),
10 => Some("01"),
11 => Some("11"),
16 => Some("91"),
_ => None
}
}
 
fn main() {
// if the number from 0 to 36 inclusive, is a perfect square and its square root is also a
// valid number when looking upside down, then we will get a Some containing the string slice,
// otherwise we get a None, indicating it's not a perfect square or the square root is not a
// valid number while looking upside down
(0..=36)
.map(|x| arithmetic_square_root(x).and_then(upside_down_num))
.enumerate()
.for_each(|(i, upside_down_square_root)|
println!("i = {i:02}, upside down square root = {upside_down_square_root:?}"));
}
</syntaxhighlight>
 
{{out}}
<pre>
i = 00, upside down square root = Some("0")
i = 01, upside down square root = Some("1")
i = 02, upside down square root = None
i = 03, upside down square root = None
i = 04, upside down square root = None
i = 05, upside down square root = None
i = 06, upside down square root = None
i = 07, upside down square root = None
i = 08, upside down square root = None
i = 09, upside down square root = None
i = 10, upside down square root = None
i = 11, upside down square root = None
i = 12, upside down square root = None
i = 13, upside down square root = None
i = 14, upside down square root = None
i = 15, upside down square root = None
i = 16, upside down square root = None
i = 17, upside down square root = None
i = 18, upside down square root = None
i = 19, upside down square root = None
i = 20, upside down square root = None
i = 21, upside down square root = None
i = 22, upside down square root = None
i = 23, upside down square root = None
i = 24, upside down square root = None
i = 25, upside down square root = None
i = 26, upside down square root = None
i = 27, upside down square root = None
i = 28, upside down square root = None
i = 29, upside down square root = None
i = 30, upside down square root = None
i = 31, upside down square root = None
i = 32, upside down square root = None
i = 33, upside down square root = None
i = 34, upside down square root = None
i = 35, upside down square root = None
i = 36, upside down square root = Some("9")
</pre>
 
=={{header|Swift}}==
{{works with|Swift|5}}
Swift has a "Maybe" type built in, called "Optional". I created a typealias so I could adhere to the naming convention. The unit function is also strictly unnecessary because Optional's constructor serves the same purpose. bind is also strictly unnecessary because Swift's Optional.flatmap function does the same thing.
 
I also created an infix operator analogous to Haskell's >>=. I can't use >>= itself because it already exists (left shift assignment) and I can't control the precedence.
 
<syntaxhighlight lang="Swift">
precedencegroup MonadPrecedence {
higherThan: BitwiseShiftPrecedence
associativity: left
}
 
infix operator >>-: MonadPrecedence // Monadic bind
 
typealias Maybe = Optional
 
extension Maybe
{
static func unit(_ x: Wrapped) -> Maybe<Wrapped>
{
return Maybe(x)
}
 
func bind<T>(_ f: (Wrapped) -> Maybe<T>) -> Maybe<T>
{
return self.flatMap(f)
}
 
static func >>- <U>(_ m: Optional<Wrapped>, _ f: (Wrapped) -> Maybe<U>) -> Maybe<U>
{
return m.flatMap(f)
}
}
 
func dividedBy2IfEven(_ x: Int) -> Maybe<Int>
{
x.isMultiple(of: 2) ? x / 2 : nil
}
 
func lineOfAs(_ x: Int) -> Maybe<String>
{
guard x >= 0 else { return nil }
let chars = Array<Character>(repeating: "A", count: x)
return String(chars)
}
 
print("\(Maybe.unit(6).bind(dividedBy2IfEven).bind(lineOfAs) ?? "nil")")
print("\(Maybe.unit(4) >>- dividedBy2IfEven >>- lineOfAs ?? "nil")")
print("\(Maybe.unit(3) >>- dividedBy2IfEven >>- lineOfAs ?? "nil")")
print("\(Maybe.unit(-4) >>- dividedBy2IfEven >>- lineOfAs ?? "nil")")
</syntaxhighlight>
 
{{out}}
<pre>
AAA
AA
nil
nil
</pre>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-fmt}}
<langsyntaxhighlight ecmascriptlang="wren">import "./fmt" for Fmt
 
class Maybe {
Line 1,582 ⟶ 2,143:
var s1 = (m1.value) ? "%(m1.value)" : "none"
var s2 = (m2.value) ? "%(m2.value)" : "none"
SystemFmt.print("%(Fmt.$4s -> $s(4", s1), s2) -> %(s2)")
}</langsyntaxhighlight>
 
{{out}}
Line 1,599 ⟶ 2,160:
 
Here we use the Void object as Nothing and define some functions. Since zkl is type-less, we can consider Maybe as a native type and don't need to define it.
<langsyntaxhighlight lang="zkl">fcn bind(a,type,b){ if(type.isType(a)) b else Void }
fcn just(x){ if(Deferred.isType(x)) x() else x } // force lazy evaluation
fcn rtn(x) { just(x) }</langsyntaxhighlight>
Since zkl is eager, add needs to gyrate a bit by creating a lazy result and evaluating that after the binds have done their bizness.
<langsyntaxhighlight lang="zkl">fcn add(mx,my){
bind(mx,Int,
bind(my,Int,
Line 1,610 ⟶ 2,171:
add(1,2).println(); // two ints
add(1,2.0).println(); // int and float
add(self,2).println(); // class and int</langsyntaxhighlight>
{{out}}
<pre>
2,122

edits