rspp-0.1.0.1: A Rational Street Performer Protocol solver

Safe HaskellSafe-Inferred
LanguageHaskell98

RSPP

Contents

Description

This module implements a solver for the Rational Street Performer Protocol.

Typical usage:

Gather a collection of pledges. They can be for a fixed amount, or a pledge based on the total raised:

import RSPP
import Data.Fixed -- for our money type

type Money = Centi

pledges :: [Pledge Money]
pledges =
  [ Pledge [RationalPledge 100.00 5.00 1.00] 250.00                   -- Pledge $1 for every $5 raised above $100, up to a limit of $250
  , Pledge [FixedPledge 50.00, RationalPledge 25.00 2.00 1.00] 500.00 -- Pledge $50, plus $1 for every $2 raised above $25, up to a limit of $500
  , Pledge [FixedPledge 200.00] 200.00                                -- Pledge $200
  ]

Find the total amount that these pledges will raise:

total :: Money
total = solve pledges -- 725.00

Find out how much each pledge evaluates to:

pledgeAmounts :: [Money]
pledgeAmounts = fmap (evalPledge total) pledges -- [125.00, 400.00, 200.00]

Synopsis

Types

Pledge

data Pledge c Source

A single pledge. Collect these in a Foldable (ie. List), and calculate the total with solve. The c type parameter is for your currency datatype, ie. Centi from Data.Fixed.

Constructors

Pledge 

Fields

pledgeClauses :: [PledgeClause c]

A list of clauses in this pledge

pledgeLimit :: c

This pledge may never exceed this amount

Instances

Eq c => Eq (Pledge c) 
Read c => Read (Pledge c) 
Show c => Show (Pledge c) 

PledgeClause

data PledgeClause c Source

A clause within a pledge, describing its behaviour. The clauses within the pledge are added together, but may never exceed the pledgeLimit.

Constructors

FixedPledge c

Simply contribute a fixed amount

RationalPledge

Contribute rpPerUnit for every rpUnit raised above rpAbove

Fields

rpAbove :: c
 
rpPerUnit :: c
 
rpUnit :: c
 

Instances

Eq c => Eq (PledgeClause c) 
Read c => Read (PledgeClause c) 
Show c => Show (PledgeClause c) 

Functions

solve Source

Arguments

:: (Foldable t, Ord c, Fractional c) 
=> t (Pledge c)

All pledges

-> c

The maximum consistent total

The key function: it does a binary search to find the maximum total which satisfies all pledges.

evalClause Source

Arguments

:: (Ord c, Fractional c) 
=> c

The total raised, including this clause

-> PledgeClause c

The clause to evaluate

-> c

What this clause contributes to the given total

Given a particular total, how much did this clause contribute to that total?

evalPledge Source

Arguments

:: (Ord c, Fractional c) 
=> c

The total raised, including this pledge

-> Pledge c

The pledge to evaluate

-> c

What this pledge contributes to the given total

Given a particular total, how much of it was this pledge? Note: the given total includes the total of this pledge!

evalPledges Source

Arguments

:: (Foldable t, Ord c, Fractional c) 
=> c

The total to evaluate against

-> t (Pledge c)

All pledges

-> c

The total of all pledges evaluated against the given total

Given a particular total, what is the total of all the pledges? Note: This may not give a valid result! Use solve for that.

pledgeMax :: Pledge c -> c Source

The most this pledge could contribute. This currently just uses the pledge's limit, though this may not always be quite right. Consider the following pledge: Pledge [FixedPledge 10] 100 The limit of 100 will certainly never be reached.

pledgeMin :: (Ord c, Fractional c) => Pledge c -> c Source

The least this pledge may contribute. May be above 0 if it contains a FixedPledge clause.

maxPledges :: (Foldable t, Num c) => t (Pledge c) -> c Source

The highest conceivable total that these pledges may contribute, based on their limits. Note that it may not be possible to actually reach this total.

minPledges :: (Foldable t, Ord c, Fractional c) => t (Pledge c) -> c Source

The lowest conceivable total that these pledges may contribute.