-- Here's what we've got with Optional
data Optional a
= Full a
| Empty
deriving Show (Eq, Show)
mapOptional :: (a -> b) -> Optinoal a -> Optional b
mapOptional _ Empty = Empty
mapOptional f (Full a) = Full (f a)
bindOptional :: (a -> Optional b) -> Optional a -> Optional b
bindOptional _ Empty = Empty
bindOptional f (Full a) = f a
applyOptional :: Optional (a -> b) -> Optional a -> Optional b
applyOptional f a = bindOptional (\f' -> mapOptional f' a) f
twiceOptional :: (a -> b -> c) -> Optional a -> Optional b -> Optional c
twiceOptional f = applyOptional . mapOptional f
-- | Convert a list of optional values to an optional list of values.
--
-- * If the list contains all `Full` values,
-- then return `Full` list of values.
--
-- * If the list contains one or more `Empty` values,
-- then return `Empty`.
--
-- * The only time `Empty` is returned is
-- when the list contains one or more `Empty` values.
--
-- >>> seqOptional (Full 1 :. Full 10 :. Nil)
-- Full [1,10]
--
-- >>> seqOptional Nil
-- Full []
--
-- >>> seqOptional (Full 1 :. Full 10 :. Empty :. Nil)
-- Empty
--
-- >>> seqOptional (Empty :. map Full infinity)
-- Empty
seqOptional ::
List (Optional a)
-> Optional (List a)
seqOptional =
foldRight (twiceOptional (:.)) (Full Nil)
Things I don't understand:
- We are passing three arguments to the twice function.
twiceOptional :: (a -> b -> c) -> Optional a -> Optional b -> Optional c
twiceOptional f = applyOptional . mapOptional f
mapOptional on the other hand takes only two arguments. Why mapOptional doesn't get angry? The partial application here works like this:
twiceOptional (+) (Full 1) (Full 2) = applyOptional . mapOptional f (Full 1) (Full 2)
2.
>>> seqOptional (Empty :. map Full infinity)
Empty
seqOptional shows that it will stop execution when it encounters the first Empty value. Why it stops execution?
Top comments (1)
bindOptional
encounters anEmpty
it does not evaluate further and just returnsEmpty