The Option type provides a type-safe way to represent values that may or may not be present, eliminating the need for null values and preventing null pointer errors at compile time.
In many languages, the absence of a value is represented by null or nil, leading to runtime errors:
// JavaScript - runtime error!let user = getUser(id); // might be nullconsole.log(user.name); // crashes if user is null
Elara uses the Option type to make optionality explicit in the type system:
-- Elara - compile-time safety!def getUser : Int -> Option Userlet user = getUser idmatch user with Some u -> println u.name -- Safe: u is guaranteed to exist None -> println "User not found"
import Optionimport Elara.Prim-- Explicit constructionlet hasValue : Option Int = Some 42let noValue : Option Int = None-- From computationdef safeDiv : Int -> Int -> Option Intlet safeDiv x y = if y == 0 then None else Some (x / y)let result1 = safeDiv 10 2 -- Some 5let result2 = safeDiv 10 0 -- None
Returns True if the option contains a value, False otherwise.
Signature:
def isSome : Option a -> Bool
Description:Checks whether an Option contains a value (is Some) or is empty (is None).Example:
import Optionlet x = Some 42let y = Nonelet hasX = isSome x -- Truelet hasY = isSome y -- False
Implementation:
let isSome opt = match opt with Some _ -> True None -> False
When to use isSome
Use isSome when you only need to check for presence without accessing the value. For most cases, pattern matching is more idiomatic as it lets you safely extract the value:
-- Less idiomaticif isSome opt then -- Still need to pattern match to get value match opt with Some x -> ...-- More idiomaticmatch opt with Some x -> ... -- Handle value None -> ... -- Handle absence
import Optiontype User = User String (Option String) -- name, optional emaildef getUserEmail : Option User -> Option Stringlet getUserEmail opt = match opt with None -> None Some (User _ email) -> emaillet user = Some (User "Alice" (Some "[email protected]"))let email = getUserEmail user -- Some "[email protected]"
import Optiondef getOrDefault : a -> Option a -> alet getOrDefault default opt = match opt with Some x -> x None -> defaultlet value = getOrDefault 0 (Some 42) -- 42let value2 = getOrDefault 0 None -- 0
import Optionimport Elara.Primdef safeDiv : Int -> Int -> Option Intlet safeDiv x y = if y == 0 then None else Some (x / y)-- Usagelet result = safeDiv 10 2match result with Some quotient -> println ("Result: " ++ toString quotient) None -> println "Cannot divide by zero"
import Optionimport Elara.Primdef safeHead : List a -> Option alet safeHead list = match list with Nil -> None Cons x _ -> Some xlet first = safeHead [1, 2, 3] -- Some 1let empty = safeHead [] -- None
import Option-- Map over Option (if you define map)def mapOption : (a -> b) -> Option a -> Option blet mapOption f opt = match opt with Some x -> Some (f x) None -> None-- Flatten nested Optionsdef flatten : Option (Option a) -> Option alet flatten opt = match opt with Some inner -> inner None -> None-- Chain operationslet result = Some 5 |> mapOption (\x -> x * 2) -- Some 10 |> mapOption (\x -> x + 1) -- Some 11
import Option-- Map: Transform the value inside an Optiondef map : (a -> b) -> Option a -> Option blet map f opt = match opt with Some x -> Some (f x) None -> None-- Bind: Chain operations that return Optionsdef bind : Option a -> (a -> Option b) -> Option blet bind opt f = match opt with Some x -> f x None -> None-- Filter: Keep only values that satisfy a predicatedef filter : (a -> Bool) -> Option a -> Option alet filter p opt = match opt with Some x -> if p x then Some x else None None -> None
import Option-- Combine two Options with a functiondef map2 : (a -> b -> c) -> Option a -> Option b -> Option clet map2 f optA optB = match (optA, optB) with (Some a, Some b) -> Some (f a b) _ -> None-- Example: Add two optional numberslet sum = map2 (\x y -> x + y) (Some 5) (Some 10) -- Some 15let noSum = map2 (\x y -> x + y) (Some 5) None -- None
import Optionimport Resultdef optionToResult : e -> Option a -> Result e alet optionToResult err opt = match opt with Some x -> Ok x None -> Err errlet result = optionToResult "Value not found" (Some 42)-- Ok 42let result2 = optionToResult "Value not found" None-- Err "Value not found"
-- Use Option when absence is not an errordef findUser : String -> Option Userlet findUser name = -- Returns None if user not found -- This is expected, not an error