swish-0.2.1: Swish/HaskellUtils/AccumulateM.hs
{-# OPTIONS -XMultiParamTypeClasses #-}
{-# OPTIONS -XFunctionalDependencies #-}
{-# OPTIONS -XFlexibleInstances #-}
--------------------------------------------------------------------------------
-- $Id: AccumulateM.hs,v 1.3 2004/01/22 19:53:46 graham Exp $
--
-- Copyright (c) 2003, G. KLYNE. All rights reserved.
-- See end of this file for licence information.
--------------------------------------------------------------------------------
-- |
-- Module : AccummulateM
-- Copyright : (c) 2003, Graham Klyne
-- License : GPL V2
--
-- Maintainer : Graham Klyne
-- Stability : provisional
-- Portability : H98
--
-- This module defines a monadic accumulator type. The plan is that it be
-- used in conjunction with FunctorM and similar constructs to accumulate
-- some or all of the values visited.
--
-- Using a monad of type Accumulator, which wraps some type 'c' and is
-- also declared to be an instance of MonadAccum Accumulator c e, for some e,
-- then foldM can be used to accumulate values of type e with an initial
-- value of type c with the instance-supplied growVal method.
--
-- This module also declares accumulator instances for Int, Integer and list
-- datatypes.
--
-- This is all very well, but rather unnecessary: it is just as easy, and
-- more standard (hence easier for other Haskell programmers to follow),
-- to use a state monad with a nullary return type; e.g.
-- execsState (stateMonadExpr) initialState
-- which returns the final state value.
--
--------------------------------------------------------------------------------
module Swish.HaskellUtils.AccumulateM
( Accumulator(..) )
where
import Control.Monad
( foldM )
class (Monad m) => MonadAccum m c e | m c -> e where
growVal :: c -> e -> m c
reapVal :: m c -> c
data Accumulator c = Accumulator c deriving (Eq, Show)
instance Monad Accumulator where
(Accumulator v) >>= k = k v
return v = Accumulator v
instance MonadAccum Accumulator Int Int where
growVal n m = Accumulator (n+m)
reapVal (Accumulator n) = n
instance MonadAccum Accumulator Integer Integer where
growVal n m = Accumulator (n+m)
reapVal (Accumulator n) = n
instance MonadAccum Accumulator [v] v where
growVal vs v = Accumulator (v:vs)
reapVal (Accumulator vs) = vs
-- Tests
addVal :: Int -> Int -> (Accumulator Int)
addVal m n = Accumulator (n+m)
testList = [1,2,3,4,5,6] :: [Int]
testList1 = [1,2,3,4,5,6] :: [Integer]
testList2 = "plugh"
test1 = foldM addVal 0 testList
test2 = Accumulator 0
test3 = (Accumulator 0) >>= addVal 1
test4 = (Accumulator 5) >>= addVal 5
test5 = (growVal 3 :: Int -> Accumulator Int) 20
test6 = foldM growVal 0 testList :: Accumulator Int
test7 = foldM growVal 0 testList1 :: Accumulator Integer
test8 = reapVal (foldM growVal 0 testList :: Accumulator Int)
test9 = reapVal (foldM growVal [] testList2 :: Accumulator [Char])
test = and
[ test1 == Accumulator 21
, test2 == Accumulator 0
, test3 == Accumulator 1
, test4 == Accumulator 10
, test5 == Accumulator 23
, test6 == Accumulator 21
, test7 == Accumulator 21
, test8 == 21
, test9 == "hgulp"
]
--------------------------------------------------------------------------------
--
-- Copyright (c) 2003, G. KLYNE. All rights reserved.
--
-- This file is part of Swish.
--
-- Swish is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- Swish is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with Swish; if not, write to:
-- The Free Software Foundation, Inc.,
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--
--------------------------------------------------------------------------------
-- $Source: /file/cvsdev/HaskellUtils/AccumulateM.hs,v $
-- $Author: graham $
-- $Revision: 1.3 $
-- $Log: AccumulateM.hs,v $
-- Revision 1.3 2004/01/22 19:53:46 graham
-- Sync.
--
-- Revision 1.2 2004/01/13 17:12:08 graham
-- Complete functionality of AccumulateM, using functional dependencies
-- in the MonadAccum type class.
--
-- Revision 1.1 2004/01/13 12:31:24 graham
-- Move modules from HaskellRDF to HaskellUtils project
--
-- Revision 1.2 2003/09/24 18:50:52 graham
-- Revised module format to be Haddock compatible.
--
-- Revision 1.1 2003/06/12 00:49:04 graham
-- Basic query processor runs test cases OK.
-- Proof framework compiles, not yet tested.
--