Module

Data.Veither

#Veither

newtype Veither errorRows a

Constructors

Instances

#_veither

_veither :: Proxy "_"

Proxy type for Veither's happy path (e.g. Either's Right constructor).

Note: the label "_" intentionally doesn't match the name of this value (i.e. '_veither').

#veither

veither :: forall errorRows a b. (Variant errorRows -> b) -> (a -> b) -> Veither errorRows a -> b

Convert a Veither into a value by defining how to handle each possible value. Below is an example of the typical usage.

consume :: Veither (a :: Int, b :: String, c :: Boolean) Number -> String
consume v = veither handleError handleSuccess v
  where
  handleError :: Variant (a :: Int, b :: String, c :: Boolean)
  handleError =
    case_
      # on (Proxy :: Proxy "a") show
      # on (Proxy :: Proxy "b") show
      # on (Proxy :: Proxy "c") show

  handleSuccess :: Number -> String
  handleSuccess = show

#vsafe

vsafe :: forall a. Veither () a -> a

Extract the value out of the Veither when there are no other possible values

vsafe (pure x) == x

#vhandle

vhandle :: forall sym b otherErrorRows errorRows a. IsSymbol sym => Cons sym b otherErrorRows errorRows => Proxy sym -> (b -> a) -> Veither errorRows a -> Veither otherErrorRows a

Removes one of the possible error types in the Veither by converting its value to a value of type a, the 'happy path' type. This can be useful for gradually picking off some of the errors the Veither value could have by handling only some of them at a given point in your code.

If the number of errors in your Veither are small and can all be handled via vhandle, one can use vsafe to extract the value of the 'happy path' a type.

foo :: Veither (b :: Int) String
foo = pure "2"

_b :: Proxy "b"
_b = Proxy

bar :: Veither (b :: Int) String
bar = Veither (inj_ _b 3)

vhandle _b show bar == ((pure "3") :: Veither () String)
vhandle _b show foo == ((pure "2") :: Veither () String)

safe (vhandle _b show bar) == "3"
safe (vhandle _b show foo) == "2"

#vhandleErrors

vhandleErrors :: forall handlers rlHandlers handledRows remainingErrorRows allErrorRows a. RowToList handlers rlHandlers => VariantMatchCases rlHandlers handledRows a => Union handledRows (_ :: a | remainingErrorRows) (_ :: a | allErrorRows) => Record handlers -> Veither allErrorRows a -> Veither remainingErrorRows a

Removes one, some, or all of the possible error types in the Veither by converting its value to a value of type a, the 'happy path' type.

Note: you will get a compiler error unless you add annotations to the record argument. You can do this by defining defining the record using a let statement or by annotating it inline (e.g. { a: identity} :: { a :: Int -> Int }`).

If all errors are handled via vhandleErrors, one can use vsafe to extract the value of the 'happy path' a type.

Doing something like vhandleErrors {"_": \(i :: Int) -> i} v will fail to compile. If you want to handle all possible values in the Veither, use veither or Data.Variant.onMatch directly (e.g. onMatch record <<< un Veither) instead of this function.

Example usage:

_a :: Proxy "a"
_a = Proxy

_b :: Proxy "b"
_b = Proxy

va :: Veither (a :: Int, b :: Boolean, c :: List String) String
va = Veither $ inj _a 4

vb :: Veither (a :: Int, b :: Boolean, c :: List String) String
vb = Veither $ inj _b false

handlers :: Record (a :: Int -> String, b :: Boolean -> String)
handlers = { a: show, b: show }

vhandleErrors handlers va == ((pure "4") :: Veither (c :: List String) String)
vhandleErrors handlers vb == ((pure "false") :: Veither (c :: List String) String)

#vfromEither

vfromEither :: forall sym otherRows errorRows a b. IsSymbol sym => Cons sym a otherRows (_ :: b | errorRows) => Proxy sym -> Either a b -> Veither errorRows b

Convert an Either into a Veither.

p :: Proxy "foo"
p = Proxy

vfromEither p (Left Int)  :: forall a. Variant (foo :: Int) a
vfromEither p (Right Int) :: forall a. Variant (foo :: a  ) Int

#vfromRight

vfromRight :: forall errorRows a. a -> Veither errorRows a -> a

Extract the value from a Veither, using a default value in case the underlying Variant is storing one of the error rows' values.

vError :: Veither (foo :: Int) String
vError = Veither (inj (Proxy :: Proxy "foo") 4)

vSuccess :: Veither (foo :: Int) String
vSuccess = pure "yay"

vfromRight "" vError   == ""
vfromRight "" vSuccess == "yay"

#vfromRight'

vfromRight' :: forall errorRows a. (Unit -> a) -> Veither errorRows a -> a

Same as vfromRight but the default value is lazy.

#vfromLeft

vfromLeft :: forall errorRows a b. b -> (Variant errorRows -> b) -> Veither errorRows a -> b

Extract the error value from a Veither, using a default value in case the underlying Variant is storing the ("_" :: a) rows' values.

vError :: Veither (foo :: Int) String
vError = Veither (inj (Proxy :: Proxy "foo") 4)

vSuccess :: Veither (foo :: Int) String
vSuccess = pure "yay"

vfromLeft  8 (case_ # on (Proxy :: Proxy "foo") identity) vError   == 4
vfromRight 8 (case_ # on (Proxy :: Proxy "foo") identity) vSuccess == 8

#vfromLeft'

vfromLeft' :: forall errorRows a b. (Unit -> b) -> (Variant errorRows -> b) -> Veither errorRows a -> b

Same as vfromLeft but the default value is lazy.

#vnote

vnote :: forall otherErrorRows errorRows s a b. Cons s a otherErrorRows (_ :: b | errorRows) => IsSymbol s => Proxy s -> a -> Maybe b -> Veither errorRows b

Convert a Maybe value into a Veither value using a default value when the Maybe value is Nothing.

mJust :: Maybe String
mJust = Just "x"

mNothing :: Maybe String
mNothing = Nothing

_foo :: Proxy "foo"
_foo = Proxy

vnote _foo 2 mJust    == (pure "y")             :: Veither (foo :: Int) String
vnote _foo 2 mNothing == (Veither (inj _foo 2)) :: Veither (foo :: Int) String

#vnote'

vnote' :: forall otherErrorRows errorRows s a b. Cons s a otherErrorRows (_ :: b | errorRows) => IsSymbol s => Proxy s -> (Unit -> a) -> Maybe b -> Veither errorRows b

Same as vnote but the default value is lazy.

#vhush

vhush :: forall errorRows a. Veither errorRows a -> Maybe a

Convert a Veither value into a Maybe value.

#genVeitherUniform

genVeitherUniform :: forall a errorRows otherGenRows rowList. RowToList (_ :: Gen a | otherGenRows) rowList => GenVariantUniform (_ :: Gen a | otherGenRows) rowList (_ :: a | errorRows) => { _ :: Gen a | otherGenRows } -> Gen (Veither errorRows a)

Generate Veither with uniform probability given a record whose generators' labels correspond to the Veither's labels

-- Note: type annotations are needed! Otherwise, you'll get compiler errors.
quickCheckGen do
  v <- genVeitherUniform
     -- first approach: annotate inline
     { "_": genHappyPath :: Gen Int
     , x: genXValues :: Gen (Maybe String)
     , y: pure "foo" :: Gen String
     }
  -- rest of test...

quickCheckGen do
  let
    -- second approach: use a let with annotations before usage
    r :: { "_" :: Gen Int, x :: Gen (Maybe String), y :: Gen String }
    r = { "_": genHappyPath, x: genXValues, y: pure "foo" }
  v <- genVeitherUniform r
  -- rest of test...

#genVeitherFrequncy

genVeitherFrequncy :: forall a errorRows otherGenRows rowList. RowToList (_ :: Tuple Number (Gen a) | otherGenRows) rowList => GenVariantFrequency (_ :: Tuple Number (Gen a) | otherGenRows) Number rowList (_ :: a | errorRows) => { _ :: Tuple Number (Gen a) | otherGenRows } -> Gen (Veither errorRows a)

Generate Veither with user-specified probability given a record whose generators' labels correspond to the Veither's labels

-- Note: type annotations are needed! Otherwise, you'll get compiler errors.
quickCheckGen do
  v <- genVeitherFrequency
     -- first approach: annotate inline
     { "_": genHappyPath :: Gen Int
     , x: genXValues :: Gen (Maybe String)
     , y: pure "foo" :: Gen String
     }
  -- rest of test...

quickCheckGen do
  let
    -- second approach: use a let with annotations before usage
    r :: { "_" :: Gen Int, x :: Gen (Maybe String), y :: Gen String }
    r = { "_": genHappyPath, x: genXValues, y: pure "foo" }
  v <- genVeitherFrequency r
  -- rest of test...

#VariantArbitrarys

class VariantArbitrarys finalRow currentRL  where

Members

Instances

#UnknownVariantValue

#VariantCoarbitrarys

class VariantCoarbitrarys currentRL  where

Members

Instances

#GenVariantUniform

class GenVariantUniform recordRows rl variantRows | recordRows -> variantRows where

Members

Instances

#GenVariantFrequency

class GenVariantFrequency recordRows b rl variantRows | recordRows -> b variantRows where

Members

Instances

Modules