7KZP4RHZ3QSYTPPQ257A65Z5UPX44TF2LAI2U5EMULQCLDCEUK2AC
FD7SV5I6VCW27HZ3T3K4MMGB2OYGJTPKFFA263TNTAMRJGQJWVNAC
IZEVQF627FA7VV25KJAWYWGGC35LZUUBBQRPN5ZAINTQLPEDRTEAC
TNR3TEHKVADAEZSTOD2XLSUTSW5AWST2YUW4CWK5KE7DSC6XHZNAC
EZQG2APB36DDMIAYDPPDGOIXOD7K2RZZSGC2NKGZIHB2HZBTW7EQC
A6HKMINBNGQLLX4QJMYWKQ4JAEHVJ4HIRVDKPPDI3FJUO2AAB7OQC
EQXRXRZDYCM7BDAVBOXQYPG6C7IJT3OFGNIXCDAHJJBRKAXNGL7AC
7XN3I3QJHYMKU2DCUXX34WQMSJ4ZJOWW7FME34EANO3E5W4Q632AC
EMVTF2IWNQGRL44FC4JNG5FYYQTZSFPNM6SOM7IAEH6T7PPK2NVAC
Z7KS5XHHC6PAMTVBHXY7KUSS3BWAOU6FSYIITUCFOOJZU4OUJHBAC
RSEB2NFGUBTFESE5BJKDUVQL5Y5ZVGY5O4CJX2LNP63MS3NRHHZQC
7DBNV3GV773FH5ZLQWFX4RBOS4Q3CIK2RYZNNABY3ZOETYZCXRNQC
N4NDAZYTLSI2W22KT3SYXL257DBMSH3UT2BXOYM7LH7FSZAY4RLAC
TLQ72DSJD7GGPWN6HGBHAVPBRQFKEQ6KSK43U7JWWID4ZWAF47JAC
NVOCQVASZWTKQJG7GPH7KHKZZR7NUG4WLV5YY4KAIRPCJRWCZPIAC
A2J7B4SCCJYKQV3G2LDHEFNE2GUICO3N3Y5FKF4EUZW5AG7PTDWAC
GKGVYBZGPJXO7N7GLHLRNYQPXFHBQSNQN53OKRFCXLQEYDTC5I4QC
SLL7262CJUE7TZDDZZXFROHCVVDA527WA4PHXCKEGZUJF2EN5MQAC
4QX5E5ACVN57KJLCWOM4JEI6JSV4XZNCWVYPOTKSOMUW3SOMCNJAC
Y35QCWYW2OTZ27ZVTH2BA3XJTUCJ2WMLKU32ZCOCDY3AW7TIZXRAC
2OIPAQCBDIUJBXB4K2QVP3IEBIUOCQHSWSWFVMVSVZC7GHX2VK7AC
WO2MINIF4TXOHWSE7JWXRZYN64XRVLYIRFMF4SMPSOXKA2V77KMQC
64C6AWH66FDKU6UE6Z6JPX2J2GBM2JOPTH2GL6LHKAIUBGNGDZ5AC
PBD7LZYQHXAA3KLH2ZUX5GW4UFML6BQ32KXZF4KZ6OYFASUYFJ5QC
4IQVQL4TS35GL2GYZJG254TKJLL5EHMRSFT77Z4VTRZIG2TMBM3QC
OBFPJS2GHO2PEHBHGEHKIUOUAFIQHPIZXEVD2YIE3ZIE2PVMH5VAC
WZUHEZSBRKHQMNWDKVG4X6DDIQEAXTGI6IGAJ5ERPRQ3W2KUMX4QC
TCOAKCGGHOIRJCTZYEZQ3K6KCGL2LGAYGYFRGSPCHBTJJY2V6AXAC
BROSTG5KP3NUNLSYPVQID254TE47E5RKQAKLPIY7PGWETE6JNMTAC
I2KHGVD44KT4MQJXGCTVSQKMBO6TVCY72F26TLXGWRL6PHGF6RNQC
XTBSG4C7SCZUFOU2BTNFR6B6TCGYI35BWUV4PVTS3N7KNH5VEARQC
NMWWP4ZNOKHZKSJ6F5KYEREWXXR5F4UD35WOKI3EH42AZWVCTCJAC
2KZPOGRBY6KBMO76F55ZKIVOLSG3O63VP3RHRZVANXYT3OLZ3OWQC
import Data.Time.Clock
import Data.Time.LocalTime()
import Data.Thyme.Clock as C
import Data.Thyme.LocalTime()
import Data.Thyme.Format.Aeson()
The depreciation function should return a value between 0 and 1;
this result is multiplied by the length of an interval of work to determine
the depreciated value of the work.
-}
type DepF = UTCTime -> Interval -> NDT
- The depreciation function should return a value between 0 and 1;
- this result is multiplied by the length of an interval of work to determine
- the depreciated value of the work.
-}
type DepF = C.UTCTime -> Interval -> NDT
Payouts are determined by computing a depreciated duration value for
each work interval. This function computes the percentage of the total
work allocated to each address.
-}
payouts :: DepF -> UTCTime -> WorkIndex -> Payouts
- Given a depreciation function, the "current" time, and a foldable functor of log intervals,
- produce the total, depreciated length of work to be credited to an address.
-}
workCredit :: (Functor f, Foldable f) => DepF -> C.UTCTime -> f Interval -> NDT
workCredit depf ptime ivals = getSum $ F.foldMap (Sum . depf ptime) ivals
{-|
- Payouts are determined by computing a depreciated duration value for
- each work interval. This function computes the percentage of the total
- work allocated to each address.
-}
payouts :: DepF -> C.UTCTime -> WorkIndex -> Payouts
addIntervalDiff total ivals = (\dt -> (dt + total, dt)) $ workCredit dep ptime ivals
(totalTime, keyTimes) = MS.mapAccum addIntervalDiff (fromInteger 0) $ widx
in Payouts $ fmap (\kt -> toRational $ kt / totalTime) keyTimes
addIntervalDiff total ivals = (^+^ total) &&& id $ workCredit dep ptime ivals
{-|
Given a depreciation function, the "current" time, and a foldable functor of log intervals,
produce the total, depreciated length of work to be credited to an address.
-}
workCredit :: (Functor f, Foldable f) => DepF -> UTCTime -> f Interval -> NDT
workCredit depf ptime ivals =
F.foldl' (+) (fromInteger 0) $ fmap (depf ptime) ivals
(totalTime, keyTimes) = MS.mapAccum addIntervalDiff zeroV $ widx
in Payouts $ fmap ((/ toSeconds totalTime) . toSeconds) keyTimes
monthsLength :: Months -> NominalDiffTime
monthsLength (Months i) = fromInteger $ 60 * 60 * 24 * 30 * i
linearDepreciation :: Months -> Months -> DepF
linearDepreciation undepPeriod depPeriod = \ptime ival ->
let maxDepreciable :: NominalDiffTime
maxDepreciable = monthsLength undepPeriod + monthsLength depPeriod
{-|
- A very simple linear function for calculating depreciation.
-
-}
linearDepreciation :: Months -> -- ^ The number of initial months during which no depreciation occurs
Months -> -- ^ The number of months over which each logged interval will be depreciated
DepF
linearDepreciation undepPeriod depPeriod =
let monthsLength :: Months -> NDT
monthsLength (Months i) = fromSeconds $ 60 * 60 * 24 * 30 * i
import Data.Thyme.Clock
import Data.Thyme.Time
import qualified Data.Text as T
import Test.QuickCheck
instance Arbitrary EventType where
arbitrary = elements [StartWork, StopWork]
newtype EventLog = EventLog [LogEntry]
instance Arbitrary BtcAddr where
arbitrary = BtcAddr . T.pack <$> vectorOf 34 arbitrary