Commit bac1c8ef authored by Michael Hanus 's avatar Michael Hanus

Prelude and SetFunctions updated

parent c7df02b3
......@@ -44,6 +44,8 @@ module Prelude
, PEVAL
, Monad(..)
, Functor(..)
, sequence, sequence_, mapM, mapM_, foldM, liftM, liftM2, forM, forM_
, unlessM, whenM
#ifdef __PAKCS__
, (=:<<=), letrec
#endif
......@@ -1804,3 +1806,71 @@ instance Monad [] where
xs >>= f = [y | x <- xs, y <- f x]
return x = [x]
fail _ = []
----------------------------------------------------------------------------
-- Some useful monad operations which might be later generalized
-- or moved into some other base module.
--- Evaluates a sequence of monadic actions and collects all results in a list.
sequence :: Monad m => [m a] -> m [a]
sequence = foldr (\m n -> m >>= \x -> n >>= \xs -> return (x:xs)) (return [])
--- Evaluates a sequence of monadic actions and ignores the results.
sequence_ :: Monad m => [m _] -> m ()
sequence_ = foldr (>>) (return ())
--- Maps a monadic action function on a list of elements.
--- The results of all monadic actions are collected in a list.
mapM :: Monad m => (a -> m b) -> [a] -> m [b]
mapM f = sequence . map f
--- Maps a monadic action function on a list of elements.
--- The results of all monadic actions are ignored.
mapM_ :: Monad m => (a -> m _) -> [a] -> m ()
mapM_ f = sequence_ . map f
--- Folds a list of elements using a binary monadic action and a value
--- for the empty list.
foldM :: Monad m => (a -> b -> m a) -> a -> [b] -> m a
foldM _ z [] = return z
foldM f z (x:xs) = f z x >>= \z' -> foldM f z' xs
--- Apply a pure function to the result of a monadic action.
liftM :: Monad m => (a -> b) -> m a -> m b
liftM f m = m >>= return . f
--- Apply a pure binary function to the result of two monadic actions.
liftM2 :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 f m1 m2 = do x1 <- m1
x2 <- m2
return (f x1 x2)
--- Like `mapM`, but with flipped arguments.
---
--- This can be useful if the definition of the function is longer
--- than those of the list, like in
---
--- forM [1..10] $ \n -> do
--- ...
forM :: Monad m => [a] -> (a -> m b) -> m [b]
forM xs f = mapM f xs
--- Like `mapM_`, but with flipped arguments.
---
--- This can be useful if the definition of the function is longer
--- than those of the list, like in
---
--- forM_ [1..10] $ \n -> do
--- ...
forM_ :: Monad m => [a] -> (a -> m b) -> m ()
forM_ xs f = mapM_ f xs
--- Performs a monadic action unless the condition is met.
unlessM :: Monad m => Bool -> m () -> m ()
unlessM p act = if p then return () else act
--- Performs a monadic action when the condition is met.
whenM :: Monad m => Bool -> m () -> m ()
whenM p act = if p then act else return ()
----------------------------------------------------------------------------
......@@ -46,25 +46,27 @@
--- the set functions itself will be evaluated.
---
--- @author Michael Hanus, Fabian Reck
--- @version June 2017
--- @version January 2018
--- @category general
------------------------------------------------------------------------
{-# LANGUAGE CPP #-}
module SetFunctions
(set0,set1,set2,set3,set4,set5,set6,set7
(set0, set1, set2, set3, set4, set5, set6, set7
#ifdef __PAKCS__
#else
,set0With,set1With,set2With,set3With,set4With,set5With,set6With,set7With
, set0With, set1With, set2With, set3With, set4With, set5With, set6With
, set7With
#endif
,Values,isEmpty,notEmpty,valueOf
,choose,chooseValue,select,selectValue
,mapValues,foldValues,filterValues,minValue,maxValue
,values2list,printValues,sortValues,sortValuesBy
, Values, isEmpty, notEmpty, valueOf
, choose, chooseValue, select, selectValue
, mapValues, foldValues, filterValues
, minValue, minValueBy, maxValue, maxValueBy
, values2list, printValues, sortValues, sortValuesBy
) where
import List(delete)
import Sort(mergeSortBy)
import List ( delete, minimum, minimumBy, maximum, maximumBy )
import Sort ( mergeSortBy )
#ifdef __PAKCS__
import Findall
#else
......@@ -259,31 +261,32 @@ data Values a = Values (Maybe a) [a]
data Values a = Values [a]
#endif
--- Internal operation to extract all elements of a multiset of values.
valuesOf :: Values a -> [a]
#ifdef __PAKCS__
--- Is a multiset of values empty?
isEmpty :: Eq a => Values a -> Bool
isEmpty (Values firstval _) = firstval == Nothing
valuesOf (Values _ s) = s
#else
valuesOf (Values s) = s
#endif
--- Is a multiset of values not empty?
notEmpty :: Eq a => Values a -> Bool
notEmpty vs = not (isEmpty vs)
----------------------------------------------------------------------
--- Is some value an element of a multiset of values?
valueOf :: Eq a => a -> Values a -> Bool
valueOf e (Values _ s) = e `elem` s
#else
--- Is a multiset of values empty?
isEmpty :: Values _ -> Bool
isEmpty :: Values a -> Bool
#ifdef __PAKCS__
isEmpty (Values firstval _) = case firstval of Nothing -> True
Just _ -> False
#else
isEmpty (Values vs) = null vs
#endif
--- Is a multiset of values not empty?
notEmpty :: Values _ -> Bool
notEmpty :: Values a -> Bool
notEmpty vs = not (isEmpty vs)
--- Is some value an element of a multiset of values?
valueOf :: Eq a => a -> Values a -> Bool
valueOf e (Values s) = e `elem` s
#endif
valueOf e s = e `elem` valuesOf s
--- Chooses (non-deterministically) some value in a multiset of values
--- and returns the chosen value and the remaining multiset of values.
......@@ -358,11 +361,7 @@ mapValues f (Values s) = Values (map f s)
--- must be <b>commutative</b> so that the result is independent of the order
--- of applying this operation to all elements in the multiset.
foldValues :: (a -> a -> a) -> a -> Values a -> a
#ifdef __PAKCS__
foldValues f z (Values _ s) = foldr f z s
#else
foldValues f z (Values s) = foldr f z s
#endif
foldValues f z s = foldr f z (valuesOf s)
--- Keeps all elements of a multiset of values that satisfy a predicate.
filterValues :: (a -> Bool) -> Values a -> Values a
......@@ -375,41 +374,31 @@ filterValues p (Values _ s) = Values val xs
filterValues p (Values s) = Values (filter p s)
#endif
--- Returns the minimal element of a non-empty multiset of values
--- with respect to a given total ordering on the elements.
minValue :: (a -> a -> Bool) -> Values a -> a
#ifdef __PAKCS__
minValue leq (Values _ s) = minOf s
#else
minValue leq (Values s) = minOf s
#endif
where
minOf [x] = x
minOf (x:y:ys) = let m1 = minOf (y:ys)
in if leq x m1 then x else m1
--- Returns the minimum of a non-empty multiset of values
--- according to the given comparison function on the elements.
minValue :: Ord a => Values a -> a
minValue s = minimum (valuesOf s)
--- Returns the maximal element of a non-empty multiset of value
--- with respect to a given total ordering on the elements.
maxValue :: (a -> a -> Bool) -> Values a -> a
#ifdef __PAKCS__
maxValue leq (Values _ s) = maxOf s
#else
maxValue leq (Values s) = maxOf s
#endif
where
maxOf [x] = x
maxOf (x:y:ys) = let m1 = maxOf (y:ys)
in if leq x m1 then m1 else x
--- Returns the minimum of a non-empty multiset of values
--- according to the given comparison function on the elements.
minValueBy :: (a -> a -> Ordering) -> Values a -> a
minValueBy cmp s = minimumBy cmp (valuesOf s)
--- Returns the maximum of a non-empty multiset of values
--- according to the given comparison function on the elements.
maxValue :: Ord a => Values a -> a
maxValue s = maximum (valuesOf s)
--- Returns the maximum of a non-empty multiset of values
--- according to the given comparison function on the elements.
maxValueBy :: (a -> a -> Ordering) -> Values a -> a
maxValueBy cmp s = maximumBy cmp (valuesOf s)
--- Puts all elements of a multiset of values in a list.
--- Since the order of the elements in the list might depend on
--- the time of the computation, this operation is an I/O action.
values2list :: Values a -> IO [a]
#ifdef __PAKCS__
values2list (Values _ s) = return s
#else
values2list (Values s) = return s
#endif
values2list s = return (valuesOf s)
--- Prints all elements of a multiset of values.
printValues :: Show a => Values a -> IO ()
......@@ -427,10 +416,6 @@ sortValues = sortValuesBy (<=)
--- In order to ensure that the result of this operation is independent of the
--- evaluation order, the given ordering must be a total order.
sortValuesBy :: (a -> a -> Bool) -> Values a -> [a]
#ifdef __PAKCS__
sortValuesBy leq (Values _ s) = mergeSortBy leq s
#else
sortValuesBy leq (Values s) = mergeSortBy leq s
#endif
sortValuesBy leq s = mergeSortBy leq (valuesOf s)
------------------------------------------------------------------------
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment