Option
- Package
- purescript-option
- Repository
- joneshf/purescript-option
There are a few different data types that encapsulate ideas in programming.
Records capture the idea of a collection of key/value pairs where every key and value exist.
E.g. Record (foo :: Boolean, bar :: Int)
means that both foo
and bar
exist and with values all of the time.
Variants capture the idea of a collection of key/value pairs where exactly one of the key/value pairs exist.
E.g. Variant (foo :: Boolean, bar :: Int)
means that either only foo
exists with a value or only bar
exists with a value, but not both at the same time.
Options capture the idea of a collection of key/value pairs where any key and value may or may not exist.
E.g. Option (foo :: Boolean, bar :: Int)
means that either only foo
exists with a value, only bar
exists with a value, both foo
and bar
exist with values, or neither foo
nor bar
exist.
The distinction between these data types means that we can describe problems more accurately. Options are typically what you find in dynamic languages or in weakly-typed static languages. Their use cases range from making APIs more flexible to interfacing with serialization formats to providing better ergonomics around data types.
#Option Source
newtype Option (row :: Row Type)
A collection of key/value pairs where any key and value may or may not exist.
E.g. Option (foo :: Boolean, bar :: Int)
means that either only foo
exists with a value, only bar
exists with a value, both foo
and bar
exist with values, or neither foo
nor bar
exist.
Instances
(DecodeJsonOption list option, RowToList option list) => DecodeJson (Option option)
(EncodeJsonOption list option, RowToList option list) => EncodeJson (Option option)
This instance ignores keys that do not exist.
If a key does not exist in the given
Option _
, it is not added to the JSON object.If a key does exists in the given
Option _
, it encodes it like normal and adds it to the JSON object.(EqOption list option, RowToList option list) => Eq (Option option)
(OrdOption list option, RowToList option list) => Ord (Option option)
(RowToList option list, ReadForeignOption list option) => ReadForeign (Option option)
This instance ignores keys that do not exist in the given
Foreign
.If a key does not exist in the
Foreign
, it will not be added to theOption _
.If a key does exists in the
Foreign
but the value cannot be successfully read, it will fail with an error.If a key does exists in the
Foreign
and the value can be successfully read, it will be added to theOption _
.(RowToList option list, ShowOption list option) => Show (Option option)
(RowToList option list, WriteForeignOption list option) => WriteForeign (Option option)
This instance ignores keys that do not exist.
If a key does not exist in the given
Option _
, it is not added to theForeign
.If a key does exists in the given
Option _
, it writes it like normal and adds it to theForeign
.
#fromRecord Source
fromRecord :: forall record option. FromRecord record option => Record record -> Option option
The given Record record
must have no more fields than the expected Option _
.
E.g. The following definitions are valid.
option1 :: Option.Option ( foo :: Boolean, bar :: Int )
option1 = Option.fromRecord { foo: true, bar: 31 }
option2 :: Option.Option ( foo :: Boolean, bar :: Int )
option2 = Option.fromRecord {}
However, the following definitions are not valid as the given records have more fields than the expected Option _
.
-- This will not work as it has the extra field `baz`
option3 :: Option.Option ( foo :: Boolean, bar :: Int )
option3 = Option.fromRecord { foo: true, bar: 31, baz: "hi" }
-- This will not work as it has the extra field `qux`
option4 :: Option.Option ( foo :: Boolean, bar :: Int )
option4 = Option.fromRecord { qux: [] }
This is an alias for fromRecord'
so the documentation is a bit clearer.
#delete Source
delete :: forall value proxy option' option label. IsSymbol label => Cons label value option option' => Lacks label option => proxy label -> Option option' -> Option option
Removes a key from an option
someOption :: Option.Option ( foo :: Boolean, bar :: Int )
someOption = Option.fromRecord { foo: true, bar: 31 }
anotherOption :: Option.Option ( bar :: Int )
anotherOption = Option.delete (Data.Symbol.SProxy :: _ "foo") someOption
The proxy
can be anything so long as its type variable has kind Symbol
.
It will commonly be Data.Symbol.SProxy
, but doesn't have to be.
#empty Source
empty :: forall option. Option option
Creates an option with no key/values that matches any type of option.
This can be useful as a starting point for an option that is later built up.
E.g.
someOption :: Option.Option ( foo :: Boolean, bar :: Int )
someOption = Option.empty
anotherOption :: Option.Option ( foo :: Boolean, bar :: Int )
anotherOption = Option.set (Data.Symbol.SProxy :: _ "bar") 31 Option.empty
#get Source
get :: forall value proxy option' option label. IsSymbol label => Cons label value option' option => proxy label -> Option option -> Maybe value
Attempts to fetch the value at the given key from an option.
If the key exists in the option, Just _
is returned.
If the key does not exist in the option, Nothing
is returned.
E.g.
someOption :: Option.Option ( foo :: Boolean, bar :: Int )
someOption = Option.insert (Data.Symbol.SProxy :: _ "bar") 31 Option.empty
bar :: Data.Maybe.Maybe Int
bar = Option.get (Data.Symbol.SProxy :: _ "bar") someOption
The proxy
can be anything so long as its type variable has kind Symbol
.
It will commonly be Data.Symbol.SProxy
, but doesn't have to be.
#getWithDefault Source
getWithDefault :: forall value proxy option' option label. IsSymbol label => Cons label value option' option => value -> proxy label -> Option option -> value
Attempts to fetch the value at the given key from an option falling back to the default.
If the key exists in the option, Just _
is returned.
If the key does not exist in the option, Nothing
is returned.
E.g.
someOption :: Option.Option ( foo :: Boolean, bar :: Int )
someOption = Option.insert (Data.Symbol.SProxy :: _ "bar") 31 Option.empty
bar :: Int
bar = Option.getWithDefault 13 (Data.Symbol.SProxy :: _ "bar") someOption
The proxy
can be anything so long as its type variable has kind Symbol
.
It will commonly be Data.Symbol.SProxy
, but doesn't have to be.
#insert Source
insert :: forall value proxy option' option label. IsSymbol label => Cons label value option' option => Lacks label option' => proxy label -> value -> Option option' -> Option option
Adds a new key with the given value to an option.
The key must not already exist in the option.
If the key might already exist in the option, set
should be used instead.
E.g.
someOption :: Option.Option ( foo :: Boolean )
someOption = Option.empty
anotherOption :: Option.Option ( foo :: Boolean, bar :: Int )
anotherOption = Option.insert (Data.Symbol.SProxy :: _ "bar") 31 someOption
The proxy
can be anything so long as its type variable has kind Symbol
.
It will commonly be Data.Symbol.SProxy
, but doesn't have to be.
#jsonCodec Source
jsonCodec :: forall record option. JsonCodec record option => String -> Record record -> JsonCodec (Option option)
Creates a JsonCodec
for an Option _
given a Record _
of JsonCodec
s.
The String
is used in errors when decoding fails.
E.g.
type Example
= Option.Option
( foo :: Boolean
, bar :: Int
)
jsonCodec :: Data.Codec.Argonaut.JsonCodec Example
jsonCodec =
Option.jsonCodec
"Example"
{ foo: Data.Codec.Argonaut.boolean
, bar: Data.Codec.Argonaut.int
}
This is an alias for jsonCodec'
so the documentation is a bit clearer.
#modify Source
modify :: forall value' value proxy option'' option' option label. IsSymbol label => Cons label value' option'' option' => Cons label value option'' option => proxy label -> (value' -> value) -> Option option' -> Option option
Manipulates the value of a key in an option.
If the field exists in the option, the given function is applied to the value.
If the field does not exist in the option, there is no change to the option.
E.g.
someOption :: Option.Option ( foo :: Boolean, bar :: Int )
someOption = Option.insert (Data.Symbol.SProxy :: _ "bar") 31 Option.empty
anotherOption :: Option.Option ( foo :: Boolean, bar :: Int )
anotherOption = Option.modify (Data.Symbol.SProxy :: _ "bar") (_ + 1) someOption
The proxy
can be anything so long as its type variable has kind Symbol
.
It will commonly be Data.Symbol.SProxy
, but doesn't have to be.
#set Source
set :: forall value' value proxy option'' option' option label. IsSymbol label => Cons label value' option'' option' => Cons label value option'' option => proxy label -> value -> Option option' -> Option option
Changes a key with the given value to an option.
The key must already exist in the option.
If the key might not already exist in the option, insert
should be used instead.
E.g.
someOption :: Option.Option ( foo :: Boolean, bar :: Int )
someOption = Option.empty
anotherOption :: Option.Option ( foo :: Boolean, bar :: Int )
anotherOption = Option.set (Data.Symbol.SProxy :: _ "bar") 31 someOption
The proxy
can be anything so long as its type variable has kind Symbol
.
It will commonly be Data.Symbol.SProxy
, but doesn't have to be.
#toRecord Source
toRecord :: forall record option. ToRecord option record => Option option -> Record record
The expected Record record
will have the same fields as the given Option _
where each type is wrapped in a Maybe
.
E.g.
someOption :: Option.Option ( foo :: Boolean, bar :: Int )
someOption = Option.fromRecord { foo: true, bar: 31 }
someRecord :: Record ( foo :: Data.Maybe.Maybe Boolean, bar :: Data.Maybe.Maybe Int )
someRecord = Option.toRecord someOption
This is an alias for toRecord'
so the documentation is a bit clearer.
#DecodeJsonOption Source
class DecodeJsonOption (list :: RowList) (option :: Row Type) | list -> option where
A typeclass that iterates a RowList
decoding an Object Json
to an Option _
.
Members
decodeJsonOption :: forall proxy. proxy list -> Object Json -> Either String (Option option)
The
proxy
can be anything so long as its type variable has kindPrim.RowList.RowList
.It will commonly be
Type.Data.RowList.RLProxy
, but doesn't have to be.
Instances
DecodeJsonOption Nil ()
(DecodeJson value, IsSymbol label, DecodeJsonOption list option', Cons label value option' option, Lacks label option') => DecodeJsonOption (Cons label value list) option
#EncodeJsonOption Source
class EncodeJsonOption (list :: RowList) (option :: Row Type) | list -> option where
A typeclass that iterates a RowList
encoding an Option _
as Json
.
Members
encodeJsonOption :: forall proxy. proxy list -> Option option -> Json
The
proxy
can be anything so long as its type variable has kindPrim.RowList.RowList
.It will commonly be
Type.Data.RowList.RLProxy
, but doesn't have to be.
Instances
EncodeJsonOption Nil ()
(EncodeJson value, IsSymbol label, EncodeJsonOption list option', Cons label value option' option, Lacks label option') => EncodeJsonOption (Cons label value list) option
#EqOption Source
class EqOption (list :: RowList) (option :: Row Type) | list -> option where
A typeclass that iterates a RowList
converting an Option _
to a Boolean
.
Members
eqOption :: forall proxy. proxy list -> Option option -> Option option -> Boolean
The
proxy
can be anything so long as its type variable has kindPrim.RowList.RowList
.It will commonly be
Type.Data.RowList.RLProxy
, but doesn't have to be.
Instances
#FromRecord Source
class FromRecord (record :: Row Type) (option :: Row Type) where
A typeclass for converting a Record _
into an Option _
.
An instance FromRecord record option
states that we can make an Option option
from a Record record
where every field present in the record is present in the option.
E.g. FromRecord () ( name :: String )
says that the Option ( name :: String )
will have no value; and FromRecord ( name :: String ) ( name :: String )
says that the Option ( name :: String )
will have the given name
value.
Since there is syntax for creating records, but no syntax for creating options, this typeclass can be useful for providing an easier to use interface to options.
E.g. Someone can say:
Option.fromRecord' { foo: true, bar: 31 }
Instead of having to say:
Option.insert
(Data.Symbol.SProxy :: _ "foo")
true
( Option.insert
(Data.Symbol.SProxy :: _ "bar")
31
Option.empty
)
Not only does it save a bunch of typing, it also mitigates the need for a direct dependency on SProxy _
.
Members
fromRecord' :: Record record -> Option option
The given
Record record
must have no more fields than the expectedOption _
.E.g. The following definitions are valid.
option1 :: Option.Option ( foo :: Boolean, bar :: Int ) option1 = Option.fromRecord' { foo: true, bar: 31 } option2 :: Option.Option ( foo :: Boolean, bar :: Int ) option2 = Option.fromRecord' {}
However, the following definitions are not valid as the given records have more fields than the expected
Option _
.-- This will not work as it has the extra field `baz` option3 :: Option.Option ( foo :: Boolean, bar :: Int ) option3 = Option.fromRecord' { foo: true, bar: 31, baz: "hi" } -- This will not work as it has the extra field `qux` option4 :: Option.Option ( foo :: Boolean, bar :: Int ) option4 = Option.fromRecord' { qux: [] }
Instances
(FromRecordOption list record option, RowToList record list) => FromRecord record option
This instance converts a record into an option.
Every field in the record is added to the option.
Any fields in the expected option that do not exist in the record are not added.
#FromRecordOption Source
class FromRecordOption (list :: RowList) (record :: Row Type) (option :: Row Type) | list -> option record where
A typeclass that iterates a RowList
converting a Record _
into an Option _
.
Members
fromRecordOption :: forall proxy. proxy list -> Record record -> Option option
The
proxy
can be anything so long as its type variable has kindPrim.RowList.RowList
.It will commonly be
Type.Data.RowList.RLProxy
, but doesn't have to be.
Instances
FromRecordOption Nil () option
(IsSymbol label, FromRecordOption list record' option', Cons label value option' option, Cons label value record' record, Lacks label option', Lacks label record') => FromRecordOption (Cons label value list) record option
#JsonCodec Source
class JsonCodec (record :: Row Type) (option :: Row Type) where
A typeclass that converts a record of JsonCodec
s into a JsonCodec
for an option.
This is useful to provide a straight-forward JsonCodec
for an Option _
.
Members
jsonCodec' :: String -> Record record -> JsonCodec (Option option)
Creates a
JsonCodec
for anOption _
given aRecord _
ofJsonCodec
s.E.g. The
String
is used in errors when decoding fails.type Example = Option.Option ( foo :: Boolean , bar :: Int ) jsonCodec :: Data.Codec.Argonaut.JsonCodec Example jsonCodec = Option.jsonCodec "Example" { foo: Data.Codec.Argonaut.boolean , bar: Data.Codec.Argonaut.int }
Instances
(JsonCodecOption list record option, RowToList record list) => JsonCodec record option
This instance ignores keys that do not exist in the given JSON object and does not insert keys that do not exist in the given
Option _
.If a key does not exist in the JSON object, it will not be added to the
Option _
.If a key does exists in the JSON object but the value cannot be successfully decoded, it will fail with an error.
If a key does exists in the JSON object and the value can be successfully decoded, it will be added to the
Option _
.If a key does not exist in the given
Option _
, it is not added to the JSON object.If a key does exists in the given
Option _
, it encodes it like normal and adds it to the JSON object.
#JsonCodecOption Source
class JsonCodecOption (list :: RowList) (record :: Row Type) (option :: Row Type) | list -> option record where
A typeclass that iterates a RowList
converting a record of JsonCodec
s into a JsonCodec
for an option.
Members
jsonCodecOption :: forall proxy. proxy list -> Record record -> JPropCodec (Option option)
The
proxy
can be anything so long as its type variable has kindPrim.RowList.RowList
.It will commonly be
Type.Data.RowList.RLProxy
, but doesn't have to be.
Instances
JsonCodecOption Nil () ()
(IsSymbol label, JsonCodecOption list record' option', Cons label value' option' option, Cons label (JsonCodec value') record' record, Lacks label option', Lacks label record', TypeEquals value (JsonCodec value')) => JsonCodecOption (Cons label value list) record option
#OrdOption Source
class (EqOption list option) <= OrdOption (list :: RowList) (option :: Row Type) | list -> option where
A typeclass that iterates a RowList
converting an Option _
to a Boolean
.
Members
compareOption :: forall proxy. proxy list -> Option option -> Option option -> Ordering
The
proxy
can be anything so long as its type variable has kindPrim.RowList.RowList
.It will commonly be
Type.Data.RowList.RLProxy
, but doesn't have to be.
Instances
#ReadForeignOption Source
class ReadForeignOption (list :: RowList) (option :: Row Type) | list -> option where
A typeclass that iterates a RowList
attempting to read a Foreign
to an Option _
.
Members
readImplOption :: forall proxy. proxy list -> Foreign -> F (Option option)
The
proxy
can be anything so long as its type variable has kindPrim.RowList.RowList
.It will commonly be
Type.Data.RowList.RLProxy
, but doesn't have to be.
Instances
ReadForeignOption Nil ()
(IsSymbol label, Cons label value option' option, Lacks label option', ReadForeignOption list option', ReadForeign value) => ReadForeignOption (Cons label value list) option
#ShowOption Source
class ShowOption (list :: RowList) (option :: Row Type) | list -> option where
A typeclass that iterates a RowList
converting an Option _
to a List String
.
The List String
should be processed into a single String
.
Members
showOption :: forall proxy. proxy list -> Option option -> List String
The
proxy
can be anything so long as its type variable has kindPrim.RowList.RowList
.It will commonly be
Type.Data.RowList.RLProxy
, but doesn't have to be.
Instances
ShowOption Nil ()
(IsSymbol label, Show value, ShowOption list option', Cons label value option' option, Lacks label option') => ShowOption (Cons label value list) option
#ToRecord Source
class ToRecord (option :: Row Type) (record :: Row Type) | option -> record where
A typeclass for converting an Option _
into a Record _
.
Since there is syntax for operating on records, but no syntax for operating on options, this typeclass can be useful for providing an easier to use interface to options.
E.g. Someone can say:
(Option.toRecord' someOption).foo
Instead of having to say:
Option.get (Data.Symbol.SProxy :: _ "foo") someOption
Not only does it save a bunch of typing, it also mitigates the need for a direct dependency on SProxy _
.
Members
toRecord' :: Option option -> Record record
The expected
Record record
will have the same fields as the givenOption _
where each type is wrapped in aMaybe
.E.g.
someOption :: Option.Option ( foo :: Boolean, bar :: Int ) someOption = Option.fromRecord' { foo: true, bar: 31 } someRecord :: Record ( foo :: Data.Maybe.Maybe Boolean, bar :: Data.Maybe.Maybe Int ) someRecord = Option.toRecord' someOption
Instances
(ToRecordOption list option record, RowToList record list) => ToRecord option record
This instance converts an option into a record.
Every field in the option is added to a record with a
Maybe _
type.All fields in the option that exist will have the value
Just _
. All fields in the option that do not exist will have the valueNothing
.
#ToRecordOption Source
class ToRecordOption (list :: RowList) (option :: Row Type) (record :: Row Type) | list -> option record where
A typeclass that iterates a RowList
converting an Option _
into a Record _
.
Members
toRecordOption :: forall proxy. proxy list -> Option option -> Record record
The
proxy
can be anything so long as its type variable has kindPrim.RowList.RowList
.It will commonly be
Type.Data.RowList.RLProxy
, but doesn't have to be.
Instances
ToRecordOption Nil () ()
(IsSymbol label, Cons label value option' option, Cons label (Maybe value) record' record, Lacks label option', Lacks label record', ToRecordOption list option' record') => ToRecordOption (Cons label (Maybe value) list) option record
#WriteForeignOption Source
class WriteForeignOption (list :: RowList) (option :: Row Type) | list -> option where
A typeclass that iterates a RowList
writing an Option _
to a Foreign
.
Members
writeForeignOption :: forall proxy. proxy list -> Option option -> Foreign
The
proxy
can be anything so long as its type variable has kindPrim.RowList.RowList
.It will commonly be
Type.Data.RowList.RLProxy
, but doesn't have to be.
Instances
WriteForeignOption Nil ()
(IsSymbol label, Cons label value option' option, Lacks label option', WriteForeign value, WriteForeignOption list option') => WriteForeignOption (Cons label value list) option
- Modules
- Option
This instance ignores keys that do not exist in the given JSON object.
If a key does not exist in the JSON object, it will not be added to the
Option _
.If a key does exists in the JSON object but the value cannot be successfully decoded, it will fail with an error.
If a key does exists in the JSON object and the value can be successfully decoded, it will be added to the
Option _
.