Module

Data.Variant

#inj

inj :: forall proxy sym a r1 r2. Cons sym a r1 r2 => IsSymbol sym => proxy sym -> a -> Variant r2

Inject into the variant at a given label.

intAtFoo :: forall r. Variant (foo :: Int | r)
intAtFoo = inj (Proxy :: Proxy "foo") 42

#prj

prj :: forall proxy sym a r1 r2 f. Cons sym a r1 r2 => IsSymbol sym => Alternative f => proxy sym -> Variant r2 -> f a

Attempt to read a variant at a given label.

case prj (Proxy :: Proxy "foo") intAtFoo of
  Just i  -> i + 1
  Nothing -> 0

#on

on :: forall proxy sym a b r1 r2. Cons sym a r1 r2 => IsSymbol sym => proxy sym -> (a -> b) -> (Variant r1 -> b) -> Variant r2 -> b

Attempt to read a variant at a given label by providing branches. The failure branch receives the provided variant, but with the label removed.

#onMatch

onMatch :: forall rl r r1 r2 r3 b. RowToList r rl => VariantMatchCases rl r1 b => Union r1 r2 r3 => Record r -> (Variant r2 -> b) -> Variant r3 -> b

Match a Variant with a Record containing functions for handling cases. This is similar to on, except instead of providing a single label and handler, you can provide a record where each field maps to a particular Variant case.

onMatch
  { foo: \foo -> "Foo: " <> foo
  , bar: \bar -> "Bar: " <> bar
  }

Polymorphic functions in records (such as show or id) can lead to inference issues if not all polymorphic variables are specified in usage. When in doubt, label methods with specific types, such as show :: Int -> String, or give the whole record an appropriate type.

#case_

case_ :: forall a. Variant () -> a

Combinator for exhaustive pattern matching.

caseFn :: Variant (foo :: Int, bar :: String, baz :: Boolean) -> String
caseFn = case_
 # on (Proxy :: Proxy "foo") (\foo -> "Foo: " <> show foo)
 # on (Proxy :: Proxy "bar") (\bar -> "Bar: " <> bar)
 # on (Proxy :: Proxy "baz") (\baz -> "Baz: " <> show baz)

#match

match :: forall rl r r1 r2 b. RowToList r rl => VariantMatchCases rl r1 b => Union r1 () r2 => Record r -> Variant r2 -> b

Combinator for exhaustive pattern matching using an onMatch case record.

matchFn :: Variant (foo :: Int, bar :: String, baz :: Boolean) -> String
matchFn = match
  { foo: \foo -> "Foo: " <> show foo
  , bar: \bar -> "Bar: " <> bar
  , baz: \baz -> "Baz: " <> show baz
  }

#default

default :: forall a r. a -> Variant r -> a

Combinator for partial matching with a default value in case of failure.

caseFn :: forall r. Variant (foo :: Int, bar :: String | r) -> String
caseFn = default "No match"
 # on (Proxy :: Proxy "foo") (\foo -> "Foo: " <> show foo)
 # on (Proxy :: Proxy "bar") (\bar -> "Bar: " <> bar)

#expand

expand :: forall lt a gt. Union lt a gt => Variant lt -> Variant gt

Every Variant lt can be cast to some Variant gt as long as lt is a subset of gt.

#contract

contract :: forall lt gt f. Alternative f => Contractable gt lt => Variant gt -> f (Variant lt)

A Variant gt can be cast to some Variant lt, where lt is is a subset of gt, as long as there is proof that the Variant's runtime tag is within the subset of lt.

#Unvariant

newtype Unvariant r

Constructors

#Unvariant'

type Unvariant' r x = forall proxy s t o. IsSymbol s => Cons s t o r => proxy s -> t -> x

#unvariant

unvariant :: forall r. Variant r -> Unvariant r

A low-level eliminator which reifies the IsSymbol and Cons constraints required to reconstruct the Variant. This lets you work generically with some Variant at runtime.

#revariant

revariant :: forall r. Unvariant r -> Variant r

Reconstructs a Variant given an Unvariant eliminator.

#VariantEqs

class VariantEqs rl  where

Members

Instances

#VariantOrds

class VariantOrds rl  where

Members

Instances

#VariantShows

class VariantShows rl  where

Members

Instances

#VariantBounded

class VariantBounded rl  where

Members

Instances

#VariantBoundedEnums

Re-exports from Data.Variant.Internal

#Contractable

class Contractable gt lt 

Instances

#VariantMatchCases

class VariantMatchCases rl vo b | rl -> vo b

Instances

Modules