tomland-0.4.0: Bidirectional TOML parser

Safe HaskellNone
LanguageHaskell2010

Toml.Bi.Monad

Description

Contains general underlying monad for bidirectional TOML converion.

Synopsis

Documentation

data Bijection r w c a Source #

Monad for bidirectional Toml conversion. Contains pair of functions:

  1. How to read value of type a from immutable environment context r?
  2. How to store value of type a in stateful context w?

In practice instead of r we will use some Reader Toml and instead of w we will use State Toml. This approach with the bunch of utility functions allows to have single description for from/to Toml conversion.

In practice this type will always be used in the following way:

type Bi r w a = Bijection r w a a

Type parameter c if fictional. Here some trick is used. This trick is implemented in codec and described in more details in related blog post.

Constructors

Bijection 

Fields

  • biRead :: r a

    Extract value of type a from monadic context r.

  • biWrite :: c -> w a

    Store value of type c inside monadic context w and returning value of type a. Type of this function actually should be a -> w () but with such type it's impossible to have Monad and other instances.

Instances
(Monad r, Monad w) => Monad (Bijection r w c) Source # 
Instance details

Defined in Toml.Bi.Monad

Methods

(>>=) :: Bijection r w c a -> (a -> Bijection r w c b) -> Bijection r w c b #

(>>) :: Bijection r w c a -> Bijection r w c b -> Bijection r w c b #

return :: a -> Bijection r w c a #

fail :: String -> Bijection r w c a #

(Functor r, Functor w) => Functor (Bijection r w c) Source # 
Instance details

Defined in Toml.Bi.Monad

Methods

fmap :: (a -> b) -> Bijection r w c a -> Bijection r w c b #

(<$) :: a -> Bijection r w c b -> Bijection r w c a #

(Applicative r, Applicative w) => Applicative (Bijection r w c) Source # 
Instance details

Defined in Toml.Bi.Monad

Methods

pure :: a -> Bijection r w c a #

(<*>) :: Bijection r w c (a -> b) -> Bijection r w c a -> Bijection r w c b #

liftA2 :: (a -> b -> c0) -> Bijection r w c a -> Bijection r w c b -> Bijection r w c c0 #

(*>) :: Bijection r w c a -> Bijection r w c b -> Bijection r w c b #

(<*) :: Bijection r w c a -> Bijection r w c b -> Bijection r w c a #

(Alternative r, Alternative w) => Alternative (Bijection r w c) Source # 
Instance details

Defined in Toml.Bi.Monad

Methods

empty :: Bijection r w c a #

(<|>) :: Bijection r w c a -> Bijection r w c a -> Bijection r w c a #

some :: Bijection r w c a -> Bijection r w c [a] #

many :: Bijection r w c a -> Bijection r w c [a] #

(MonadPlus r, MonadPlus w) => MonadPlus (Bijection r w c) Source # 
Instance details

Defined in Toml.Bi.Monad

Methods

mzero :: Bijection r w c a #

mplus :: Bijection r w c a -> Bijection r w c a -> Bijection r w c a #

type Bi r w a = Bijection r w a a Source #

Specialized version of Bijection data type. This type alias is used in practice.

dimap Source #

Arguments

:: (Functor r, Functor w) 
=> (c -> d)

Mapper for consumer

-> (a -> b)

Mapper for producer

-> Bijection r w d a

Source Bijection object

-> Bijection r w c b 

This is an instance of Profunctor for Bijection. But since there's no Profunctor type class in base or package with no dependencies (and we don't want to bring extra dependencies) this instance is implemented as a single top-level function.

Useful when you want to parse newtypes. For example, if you had data type like this:

data Example = Example
    { foo :: Bool
    , bar :: Text
    }

toml bidirectional converter for this type will look like this:

exampleT :: BiToml Example
exampleT = Example
    $ bool "foo" .= foo
    * str  "bar" .= bar

Now if you change your time in the following way:

newtype Email = Email { unEmail :: Text }

data Example = Example
    { foo :: Bool
    , bar :: Email
    }

you need to patch your toml parser like this:

exampleT :: BiToml Example
exampleT = Example
    $ bool "foo" .= foo
    * dimap unEmail Email (str  "bar") .= bar

(<!>) :: Alternative f => (a -> f x) -> (a -> f x) -> a -> f x infixl 3 Source #

Alternative instance for function arrow but without empty.

(.=) :: Bijection r w field a -> (object -> field) -> Bijection r w object a infixl 5 Source #

Operator to connect two operations:

  1. How to get field from object?
  2. How to write this field to toml?

In code this should be used like this:

data Foo = Foo { fooBar :: Int, fooBaz :: String }

foo :: BiToml Foo
foo = Foo
 $ int "bar" .= fooBar
 * str "baz" .= fooBaz