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.Clockimport Data.Time.LocalTime()
import Data.Thyme.Clock as Cimport 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 determinethe 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 foreach work interval. This function computes the percentage of the totalwork 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 -> NDTworkCredit 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) $ widxin 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 -> NDTworkCredit depf ptime ivals =F.foldl' (+) (fromInteger 0) $ fmap (depf ptime) ivals
(totalTime, keyTimes) = MS.mapAccum addIntervalDiff zeroV $ widxin Payouts $ fmap ((/ toSeconds totalTime) . toSeconds) keyTimes
monthsLength :: Months -> NominalDiffTimemonthsLength (Months i) = fromInteger $ 60 * 60 * 24 * 30 * ilinearDepreciation :: Months -> Months -> DepFlinearDepreciation undepPeriod depPeriod = \ptime ival ->let maxDepreciable :: NominalDiffTimemaxDepreciable = monthsLength undepPeriod + monthsLength depPeriod
{-|- A very simple linear function for calculating depreciation.--}linearDepreciation :: Months -> -- ^ The number of initial months during which no depreciation occursMonths -> -- ^ The number of months over which each logged interval will be depreciatedDepFlinearDepreciation undepPeriod depPeriod =let monthsLength :: Months -> NDTmonthsLength (Months i) = fromSeconds $ 60 * 60 * 24 * 30 * i
import Data.Thyme.Clockimport Data.Thyme.Timeimport qualified Data.Text as Timport Test.QuickCheckinstance Arbitrary EventType wherearbitrary = elements [StartWork, StopWork]newtype EventLog = EventLog [LogEntry]instance Arbitrary BtcAddr wherearbitrary = BtcAddr . T.pack <$> vectorOf 34 arbitrary