packages feed

applicative-logic-0.1.0.2: src/Control/Applicative/Logic.hs

{-|
Module      : Control.Applicative.Logic
Description : Generalized logic operations for Applicative and Alternative functors
Copyright   : (c) Håkon Robbestad Gylterud, Year
License     : BSD-3-Clause
Maintainer  : lyesveasp@openbastille.org
Stability   : experimental
Portability : POSIX

This library contains a generalisation of local functions such as "any" and "all" to Applicative and Alternative functors.
-}
module Control.Applicative.Logic (any,or,all,and,(&&),convert,Searchable,search) where

import Control.Applicative
import Prelude hiding (any,all,and,or,(&&))

true :: (Applicative f, Monoid a) => f a
true = pure mempty

false :: (Alternative f) => f a
false = empty

-- | Generalized version of 'Prelude.any'. It takes a predicate that returns 
-- generalised truth values in an 'Alternative' functor and applies it disjunctively to
-- a foldable structure. I.e. it applies the predicate and folds with <|>.

any :: (Alternative f, Foldable t) => (a -> f b) -> t a -> f b
any = ($ false) . foldr . ((<|>) .)

-- | Generalized version of 'Prelude.all'. It takes a predicate that gives generalized
-- truth values in an Applicative functor on a Monoid and applies it conjunctively to
-- a foldable structure. I.e. it applies the predicate and folds with an applicative
-- lifting of monoidal concatenation ('<>').

all :: (Applicative f, Monoid b, Foldable t)
    => (a -> f b) -> t a -> f b
all = ($ true) . foldr . (liftA2 (<>) <$>)


-- | Generalized version of the boolean 'or' to foldable structures of 'Alternative' functorial values.
-- It combines the elements using the alternative choice operator ('<|>').

or :: (Alternative f, Foldable t)
   => t (f a) -> f a
or = any id

-- | Generalized version of the boolean 'and' to foldable structures of
-- 'Applicative' functor applied to monoids. It combines the elements using the
-- monoidal concatenation ('<>').

and :: (Applicative f, Monoid a, Foldable t)
    => t (f a) -> f a
and = all id

-- | Generalized version of the boolean '&&' operator for 'Applicative' functors applied to monoids.
--   It sequences and combines two applicative values using the monoidal operation ('<>').
(&&) :: (Applicative f, Monoid a)
     => f a -> f a -> f a
(&&) = liftA2 (<>)

-- | Converts a foldable structure into an 'Alternative' functor, where each element is lifted into the
-- functor using 'pure' and then combined using the alternative choice operator ('<|>').
--
convert :: (Alternative f, Foldable t)
     => t a -> f a
convert = any pure

-- | 'Searchable' class represents structures that can be searched using a predicate.
-- An instance may use 'all' or 'any' to iterate over parts of its structure depending
-- on wether the substrcutres are conjunctive or disjunctive.
class (Foldable t) => Searchable t where
    -- | Search a structure using a predicate
    search :: (Alternative f, Monoid b) => (a -> f b) -> t a -> f b

-- | 'Maybe' instance of 'Searchable'.
instance Searchable Maybe where
    search = any