A data type for untagged unions.
Consider a the following type:
import Untagged.Union
type ISB = Int |+| String |+| BooleanThe type ISB describes values which can either be an Int, a String or a Boolean. Moreover, it is guaranteed that at runtime, values of type ISB is directly stored as an Int, a String or a Boolean without any wrappers. This makes it especially useful for FFI.
Note that |+| is an alias for OneOf.
In order to create a value of OneOf, use asOneOf.
isb1 :: ISB
isb1 = asOneOf 20
isb2 :: ISB
isb2 = asOneOf "foo"
--isb3 :: ISB
--isb3 = asOneOf 3.5
-- isb3 will fail since 3.5 is a Number which is neither
-- an Int, String nor Boolean
The library also defines Undefined. Combined with OneOf, it can represent an optional type:
import Literals.Undefined
type OptionalInt = Int |+| UndefinedAn alias UndefinedOr is also provided.
type OptionalInt' = UndefinedOr Int -- Same as `Int |+| Undefined`To get a purescript value back, use fromOneOf:
import Data.Maybe
valInt :: Maybe Int
valInt = fromOneOf isb1 -- evaluates to `Just 20`
valString :: Maybe String
valString = fromOneOf isb1 -- evalutes to `Nothing` since isb1 contains an Int
Using OneOf, describing JS types as records becomes intuitive:
type Props =
{ text :: String -- a required field
-- Optional Fields
, width :: UndefinedOr Number
, height :: UndefinedOr Number
-- Optional and Varying types
, fontSize :: String |+| Number |+| Undefined
}A coerce helper is made available to convert records with the same runtime value:
import Untagged.Coercible (coerce)
sampleProps :: Props
sampleProps =
coerce { text: "foo" -- text is required and should be a string
, width: 30.0 -- width is optional, and may be defined, but should be a Number
-- height is optional and may be omitted
, fontSize: "100%" -- fontSize may be defined, and should either be a string or number
}