hs-carbon-0.0.0.2: src/Data/Result.hs
{-# LANGUAGE TypeFamilies #-}
module Data.Result
(
-- * Describing Simulation Results with Type Annotations
-- $description
Result(..)
)
where
import Control.DeepSeq
import Data.Monoid
{- $description #description#
Carbon simulations are built up from 'Control.Monad.MonteCarlo' actions.
A 'MonteCarlo' action describes how to arrive at an observation, but not how to aggregate observations.
This functionality is specified with a type annotation telling Haskell which instance of the type family 'Result' should be used.
For example, given a 'MonteCarlo' action, mySim, with type:
> mySim :: RandomGen g => MonteCarlo g Bool
We get different results based on the instance of 'Result' chosen:
> experimentS mySimulation 100 g :: [Bool]
> experimentS mySimulation 100 g :: BoolSumm
-}
-- | Result is the type family used to describe the aggregation techniques to be used in a Monte Carlo simulation.
-- Instances of Result should specify the type of a single observation and how to include one.
-- The value of a 'Result' without any observations should be specified.
-- Additionally, 'Result's should be joinable.
--
-- Note that almost all instances of 'Result' will be monoidal.
class Result r where
-- | The type of a single observation
type Obs r :: *
-- | How to add a single observation to the result
addObs :: r -> Obs r -> r
-- | How to join two results together
rjoin :: r -> r -> r
-- | The value of a result without any observations
rzero :: r
-- | One common aggregation technique is appending observations to a list.
-- In the interest of preventing thunks from building up, we force deep evaluation of observations.
instance NFData a => Result [a] where
type Obs [a] = a
addObs r o = o `deepseq` (o : r)
rjoin = mappend
rzero = mempty