applicative-fail

Applicative functor and monad which collects all your fails https://bitbucket.org/s9gf4ult/applicative-fail

Latest on Hackage:1.1.1

This package is not currently in any snapshots. If you're interested in using it, we recommend adding it to Stackage Nightly. Doing so will make builds more reliable, and allow stackage.org to host generated Haddocks.

BSD3 licensed by Aleksey Uimanov
Maintained by s9gf4ult@gmail.com

What is it for?

Assume you have some type

data Animal = Animal
    { species :: String
    , weight  :: Double
    , age     :: Int
    } deriving (Show)

And you would like to produce this value from some data (e.g. query parameters). There can be some warnigns or value can not be produced at all. It would be great to have some simple tool to notify about warnings and/or fail computation.

Like that:

let spc = "Parastratiosphecomyia stratiosphecomyioides"
    w = 100
    a = 27234
    animal :: Fail [String] Animal
    animal = Animal
             <$> (if length spc > 20
                  then awarn "Name is too long" spc
                  else if spc == ""
                       then afail "Name can not be empty"
                       else pure spc)
             <*> (if w < 0
                  then afail "Weight can not be negative"
                  else pure w)
             <*> (if a < 0
                  then afail "Age can not be negative"
                  else pure a)

Now you can inspect the value we have got

>>> animal
Fail ["Name is too long"] (Just (Animal {species = "Parastratiosphecomyia stratiosphecomyioides", weight = 100.0, age = 27234}))

>>> getSucc animal
Just (Animal {species = "Parastratiosphecomyia stratiosphecomyioides", weight = 100.0, age = 27234})

>>> getFail animal
Just ["Name is too long"]

Now this example can be rewritten with monadic syntax inside field checkers using module Control.Monad.Fail:

let animal :: Fail [String] Animal
    animal = Animal
             <$> (runFailI $ do
                          when (length spc > 20) $ mwarn "Name is too long"
                          when (spc == "") $ mfail "Name can not be empty"
                          return spc)
             <*> (runFailI $ do
                          when (w < 0) $ mfail "Weight can not be negative"
                          return w)
             <*> (runFailI $ do
                          when (a < 0) $ mfail "Age can not be negative"
                          return a)

Changes

CHANGELOG

1.1.1

Changed

  • upper base constraints relaxed

1.1.0

Added

  • mapFailTBase - map inner monad (e.g. lift)
  • mapFailTFail - map error type

1.0.0

Added

  • Module Control.Monad.Fail containing monadic version of Control.Applicative.Fail
  • Tests added: all properties (Monad, Applicative, Monoid laws) are prooved with QuickCheck and package checkers
  • runFail and runDLFail: functions to unwrap Fail
  • dependencies added: dlist, mtl, transformers

Removed

  • fsucc: use return / pure instead
  • bindFail and composeFail: use monadic fail instead

Changed

  • ffail and fwarn renamed to afail and awarn
  • afail and awarn are more generic now
  • documentation strictly improoved

0.0.3

First usable version

comments powered byDisqus