Maybe with the ability to know at the type level whether it exists.
import MaybeIs exposing (just)
[ just 1, just 7 ]
--: List (MaybeIs just_ number_)
|> List.map MaybeIs.value
--> [ 1, 7 ]MaybeIs alone will probably not proof any useful,
but we can build cool type-safe data structures with it:
type alias ListIs emptyOrNot a =
MaybeIs emptyOrNot ( a, List a )
type alias NotEmpty =
MaybeIs.Just { notEmpty : () }
type alias Emptiable =
MaybeIs.Nothingable { emptiable : () }
empty : ListIs Emptiable a_
cons : ListIs emptyOrNot_ a -> a -> ListIs notEmpty_ a
head : ListIs NotEmpty a -> aThis is exactly how ListIs is implemented.
Only allow MaybeIss that certainly exist as arguments.
import MaybeIs exposing (Just, MaybeIs)
head : MaybeIs (Just tag_) ( a, List a ) -> a
head =
MaybeIs.value >> Tuple.firstSee CanBeNothing and ListIs.
MaybeIs (Nothingable tag): The value could exist, could also not exist.
See CanBeNothing.
The value attached to a IsNothing:
Just: that value is NeverNothingable: that value is ()It also has a simple type tag to make MaybeIs values distinct:
type alias NotEmpty =
MaybeIs.Just { notEmpty : () }
type alias ItemFocussed =
MaybeIs.Just { itemFocussed : () }Remember to update the tag after renaming an alias.
A MaybeIs that certainly exists.
MaybeIs.just "you" |> MaybeIs.value
--> "you"Transform the value in the MaybeIs using a given function:
import MaybeIs exposing (just, nothing)
MaybeIs.map abs (just -3) --> just 3
MaybeIs.map abs nothing --> nothingIf all the arguments exist, combine them using a given function.
import MaybeIs exposing (just, nothing)
MaybeIs.map2 (+) (just 3) (just 4) --> just 7
MaybeIs.map2 (+) (just 3) nothing --> nothing
MaybeIs.map2 (+) nothing (just 4) --> nothingSafely extracts the value from a MaybeIs Just value.
import MaybeIs exposing (just)
just (just (just "you"))
|> MaybeIs.value
|> MaybeIs.value
|> MaybeIs.value
--> "you"Chain together many computations that may fail.
maybeString
|> MaybeIs.andThen parse
|> MaybeIs.andThen extraValidation
parse : String -> MaybeIs Nothingable Parsed
extraValidation : Parsed -> MaybeIs Nothingable ValidatedLazily use a fallback value if the MaybeIs is nothing.
import Dict
Dict.empty
|> Dict.get "Tom"
|> MaybeIs.fromMaybe
|> MaybeIs.withFallback (\() -> "unknown")
--> "unknown"Hint: MaybeIs.withFallback never is equivalent to MaybeIs.value.
When using Just/NotEmpty/... for an argument:
theShorter :
ListIs NotEmpty a
-> ListIs emptyOrNot a
-> ListIs emptyOrNot a
theShorter aList bList =
if ListIs.length bList > ListIs.length aList then
bList
else
--↓ `NotEmpty` but we need `emptyOrNot`
aListto make both branches return emptyOrNot, we could use
else
aList |> ListType.toTuple |> ListType.fromTuplealso known as: necessary code that nobody will understand.
else
aList |> MaybeIs.branchableTypeis a bit better.
💙 Found a better name? → open an issue.
Like
Maybewith type level information about whether it exists.See
JustandNothingable.