An emptiable-able value.
import Hand exposing (Empty)
import Stack exposing (Stacked)
fill : Hand fill Never Empty -> fill
top : Hand (Stacked element) Never Empty -> elementimport Hand exposing (Empty, Hand)
import Stack exposing (Stacked)
type alias Model =
WithoutConstructorFunction
{ searchKeyWords : Hand (Stacked String) Never Empty
}where RecordWithoutConstructorFunction
stops the compiler from creating a constructor function for Model.
A word used in the Hand type:
top : Hand (Stacked element) Never Empty -> element
when :
Hand ... possiblyOrNever_ Empty
-> Hand ... Possibly EmptyInsert joke about life here.
Hand.empty
|> Hand.fillMap (\x -> x / 0)
--> Hand.emptyA Hand.Empty that certainly exists, allowing type-safe extraction.
import Hand exposing (filled, fill)
filled "Bami" |> fill
--> "Bami"Chain together operations that may return empty.
It's like calling fillMap|>flatten:
If the argument Hand.Empty Never Empty,
a given function takes its fill
and returns a new possibly empty value.
Some call it
andThen
or flatMap.
import Hand exposing (Hand, Empty, fillMapFlat)
emptiableString
|> fillMapFlat parse
|> fillMapFlat extraValidation
parse : ( Char, String ) -> Hand Parsed Possibly Empty
extraValidation : Parsed -> Hand Parsed Possibly EmptyFor any number of arguments:
fillAnd... |> ... |>fillMapFlat:
import Hand exposing (filled, fillMapFlat, fillAnd)
(filled 3)
|> fillAnd (filled 4)
|> fillAnd (filled 5)
|> fillMapFlat
(\( ( a, b ), c ) -> filled ( a, b, c ))
--> filled ( 3, 4, 5 )If the incoming food and the given argument are
filled, give a filled tuple of both fills back.
If any is empty, give a Hand.empty back.
fillAnd comes in handy when multiple arguments need to be filled:
import Hand exposing (filled, fillMap, fillAnd)
filled 3
|> fillAnd (filled 4)
|> fillAnd (filled 5)
|> fillMap (\( ( a0, a1 ), a2 ) -> a0^a1 - a2^2)
--> filled 56Safely extract the filled content from a Hand fill Never Empty.
import Hand exposing (Empty, filled)
filled (filled (filled "Bami"))
|> Hand.fill
|> Hand.fill
|> Hand.fill
--> "Bami"
first : Empty ( first, others_ ) Never Empty -> first
first =
Hand.fill >> Tuple.firstLazily use a fallback value if the Hand is empty.
import Possibly exposing (Possibly(..))
import Hand exposing (Hand(..), fillElseOnEmpty)
import Dict
Dict.empty
|> Dict.get "Hannah"
|> Hand.fromMaybe
|> fillElseOnEmpty (\_ -> "unknown")
--> "unknown"
fill =
fillElseOnEmpty never
fatten =
fillElseOnEmpty EmptyConvert to a Maybe.
Don't try to use this prematurely. Keeping type information as long as possible is always a win.
Change the possiblyOrNever type.
Empty PossiblyAn Empty possiblyOrNever can't be used as Empty Possibly
import Hand exposing (Empty)
import Possibly exposing (Possibly)
import Stack exposing (Stacked)
type alias Log =
Empty Possibly (Stacked String)
fromStack : Hand (Stacked String) possiblyOrNever_ Empty -> Log
fromStack stackFilled =
stackFilled
--: `possiblyOrNever_` but we need `Possibly`
|> Hand.emptyAdapt (always Possible)Never EmptyThe Never Empty can't be unified with Possibly Empty or a type variable
import Hand exposing (Empty)
import Stack exposing (Stacked)
theShorter :
Hand (Stacked element) Never Empty
-> Hand (Stacked element) possiblyOrNever Empty
-> Hand (Stacked element) possiblyOrNever Empty
theShorter aStack bStack =
if Stack.length bStack > Stack.length aStack then
bStack
else
aStack
--: `Never` but we need `possiblyOrNever`
|> Hand.emptyAdapt nevermakes both branches return possiblyOrNever.
Like
Maybe, but able to know at type-level whetherEmptyis possible.Hand.Emptyalone probably won't be that useful, but it can make data structures type-safely non-emptiable:Go take a look at all the data structures in this package.