2019-02-01 16:07:10 +03:00
(deftype (Maybe a)
(Just [a])
(Nothing []))
2019-02-11 13:39:03 +03:00
2021-07-05 15:48:35 +03:00
(doc Maybe "is a data type to represent optional values. It has two
constructors, `(Just <value>)` and `Nothing`, and provides many functions to
wrap and unwrap values.")
2019-02-11 13:39:03 +03:00
(defmodule Maybe
2019-02-15 12:18:23 +03:00
(doc apply "applies a function to the value inside `a` if it is a `Just`, and wraps it up again. If it is `Nothing`, it is just returned.")
2019-02-11 13:39:03 +03:00
(defn apply [a f]
(match a
(Nothing) (Nothing)
2020-01-25 16:08:37 +03:00
(Just x) (Just (~f x))))
2019-02-11 13:39:03 +03:00
2019-02-15 12:18:23 +03:00
(doc unsafe-from "is an unsafe unwrapper that will get the value from a `Just`. If `a` is `Nothing`, a runtime error will be generated.")
2019-02-11 13:39:03 +03:00
(defn unsafe-from [a]
(match a
(Just x) x))
2019-02-15 12:18:23 +03:00
(doc from "is an unwrapper that will get the value from a `Just`, or a default value if a `Nothing` is passed.")
2019-02-11 13:39:03 +03:00
(defn from [a dflt]
(match a
(Nothing) dflt
(Just x) x))
2019-06-12 09:49:54 +03:00
(doc or-zero "is an unwrapper that will get the value from a `Just`, or build
a value using `zero` if a `Nothing` is passed.")
(defn or-zero [a]
(match a
(Nothing) (zero)
(Just x) x))
2019-02-15 12:18:23 +03:00
(doc just? "checks whether the given value `a` is a `Just`.
It is the inverse of [`nothing?`](#nothing?).")
2019-02-11 13:39:03 +03:00
(defn just? [a]
2020-04-30 13:57:27 +03:00
(match-ref a
2019-02-11 13:39:03 +03:00
(Nothing) false
(Just x) true))
2019-02-15 12:18:23 +03:00
(doc nothing? "checks whether the given value `a` is a `Nothing`.
It is the inverse of [`just?`](#just?).")
2019-02-11 13:39:03 +03:00
(defn nothing? [a]
2020-04-30 13:57:27 +03:00
(match-ref a
2019-02-11 13:39:03 +03:00
(Nothing) true
(Just x) false))
2019-02-15 12:18:23 +03:00
(doc = "equality is defined as the equality of both the constructor and the contained value, i.e. `(Just 1)` and `(Just 1)` are the same, but `(Just 1)` and `(Just 2)` are not.")
2019-02-11 22:24:17 +03:00
(defn = [a b]
2020-04-30 13:57:27 +03:00
(match-ref a
2019-02-11 22:24:17 +03:00
(Nothing) (nothing? b)
(Just x)
2020-04-30 13:57:27 +03:00
(match-ref b
2019-02-11 22:24:17 +03:00
(Nothing) false
(Just y) (= x y))))
2020-05-10 20:32:22 +03:00
(implements = Maybe.=)
2019-05-03 14:49:33 +03:00
2019-10-31 11:38:47 +03:00
(doc unsafe-ptr "Creates a `(Ptr a)` from a `(Maybe a)`. If the `Maybe` was
2019-05-03 14:49:33 +03:00
`Nothing`, this function will return a `NULL` value.")
2019-10-31 11:38:47 +03:00
(defn unsafe-ptr [a]
2020-05-19 00:20:45 +03:00
(match-ref a
(Nothing) NULL
(Just _) ((the (Fn [(Ref (Maybe a))] (Ptr a)) Unsafe.coerce) a)))
2019-05-03 14:49:33 +03:00
(doc from-ptr "Creates a `(Maybe a)` from a `(Ptr a)`. If the `Ptr` was
`NULL`, this function will return `Nothing`.")
(defn from-ptr [a]
(if (null? a)
(Nothing)
(Just @(Pointer.to-ref a))))
2019-06-06 21:32:55 +03:00
(doc zero "returns `Nothing`.")
(defn zero [] (Nothing))
2020-05-10 20:32:22 +03:00
(implements zero Maybe.zero)
2019-02-11 13:39:03 +03:00
)