-- Apply a pricing procedure = a list of percentual or absolute additions
-- forwards ("compute")
-- and backwards ("resolve" - which is the point here).
-- Each condition is a linear function on any of the formerly computed,
-- intermediate terms, so a condition is a function [a] -> a
percent p x = p * x / 100
-- Need a data type for conditions,
-- in order to distinguish absolute from relative conditions
data Condition a = RelativeCondition {apply :: a}
| AbsoluteCondition {apply :: a}
-- predicate function for detecting relative types
isRelative
:: Condition a
-> BoolisRelative (RelativeCondition _) = True
isRelative _ = False
condRel, condRelBase
condAbs
:: a -> Condition ([a] -> a)
condRel p
= RelativeCondition
(\ x
-> percent p
( last x
) )condRelBase p
= RelativeCondition
(\ x
-> percent p
( head x
) )condAbs q = AbsoluteCondition (\ x -> q )
-- How to compute a scheme:
-- Apply functions successively, starting with base price
compute
:: Num a
=> [Condition
([a
] -> a
)] -> a
-> a
compute scheme base
= last $ foldl (\x f
-> x
++ [ last x
+ apply f x
] ) [base
] scheme
-- How to resolve a scheme
resolve scheme result =
( result - compute scheme 0 )
/ compute (reduced scheme) 1
-- A sample calculation scheme
scheme = [
condAbs 10.00,
condRel 5.00,
condRelBase 3.25,
condAbs 20.00,
condRel 3.00,
condRelBase 2.00,
condRel 7.00,
condAbs 10.00
]
--- Reduced scheme consists only of the relative conditions
reduced :: [Condition a] -> [Condition a]
reduced scheme
= filter isRelative scheme
-- Test (should reproduce the input (100) )
main = do
print $ resolve scheme
$ compute scheme
100
LS0gQXBwbHkgYSBwcmljaW5nIHByb2NlZHVyZSA9IGEgbGlzdCBvZiBwZXJjZW50dWFsIG9yIGFic29sdXRlIGFkZGl0aW9ucwotLSAgIGZvcndhcmRzICgiY29tcHV0ZSIpCi0tICAgYW5kIGJhY2t3YXJkcyAoInJlc29sdmUiIC0gd2hpY2ggaXMgdGhlIHBvaW50IGhlcmUpLgoKLS0gRWFjaCBjb25kaXRpb24gaXMgYSBsaW5lYXIgZnVuY3Rpb24gb24gYW55IG9mIHRoZSBmb3JtZXJseSBjb21wdXRlZCwKLS0gaW50ZXJtZWRpYXRlIHRlcm1zLCBzbyBhIGNvbmRpdGlvbiBpcyBhIGZ1bmN0aW9uIFthXSAtPiBhCgpwZXJjZW50IDo6IEZyYWN0aW9uYWwgYSA9PiBhIC0+IGEgLT4gYQpwZXJjZW50IHAgeCA9IHAgKiB4IC8gMTAwCgotLSBOZWVkIGEgZGF0YSB0eXBlIGZvciBjb25kaXRpb25zLAotLSBpbiBvcmRlciB0byBkaXN0aW5ndWlzaCBhYnNvbHV0ZSBmcm9tIHJlbGF0aXZlIGNvbmRpdGlvbnMKZGF0YSBDb25kaXRpb24gYSAgPSBSZWxhdGl2ZUNvbmRpdGlvbiB7YXBwbHkgOjogYX0KICAgICAgICAgICAgICAgICAgfCBBYnNvbHV0ZUNvbmRpdGlvbiB7YXBwbHkgOjogYX0KCi0tIHByZWRpY2F0ZSBmdW5jdGlvbiBmb3IgZGV0ZWN0aW5nIHJlbGF0aXZlIHR5cGVzCmlzUmVsYXRpdmUgOjogQ29uZGl0aW9uIGEgLT4gQm9vbAppc1JlbGF0aXZlIChSZWxhdGl2ZUNvbmRpdGlvbiBfKSA9IFRydWUKaXNSZWxhdGl2ZSBfICAgICAgICAgICAgICAgICAgICAgPSBGYWxzZQoKCmNvbmRSZWwsIGNvbmRSZWxCYXNlCiAgICA6OiBGcmFjdGlvbmFsIGEgPT4gYSAtPiBDb25kaXRpb24gKFthXSAtPiBhKQpjb25kQWJzCiAgICA6OiBhIC0+IENvbmRpdGlvbiAoW2FdIC0+IGEpCmNvbmRSZWwgcCAgICAgPSBSZWxhdGl2ZUNvbmRpdGlvbiAoXCB4IC0+ICBwZXJjZW50IHAgKCBsYXN0IHggKSApCmNvbmRSZWxCYXNlIHAgPSBSZWxhdGl2ZUNvbmRpdGlvbiAoXCB4IC0+ICBwZXJjZW50IHAgKCBoZWFkIHggKSApCmNvbmRBYnMgcSAgICAgPSBBYnNvbHV0ZUNvbmRpdGlvbiAoXCB4IC0+IHEgKQoKCi0tIEhvdyB0byBjb21wdXRlIGEgc2NoZW1lOgotLSBBcHBseSBmdW5jdGlvbnMgc3VjY2Vzc2l2ZWx5LCBzdGFydGluZyB3aXRoIGJhc2UgcHJpY2UKY29tcHV0ZSA6OiBOdW0gYSA9PiBbQ29uZGl0aW9uIChbYV0gLT4gYSldIC0+IGEgLT4gYQpjb21wdXRlIHNjaGVtZSBiYXNlID0gbGFzdCAkIGZvbGRsIChceCBmIC0+IHggKysgWyBsYXN0IHggKyBhcHBseSBmIHggXSApIFtiYXNlXSBzY2hlbWUKCi0tIEhvdyB0byByZXNvbHZlIGEgc2NoZW1lCnJlc29sdmUgc2NoZW1lIHJlc3VsdCA9CiAgICggcmVzdWx0IC0gY29tcHV0ZSBzY2hlbWUgMCApCiAgICAgLyBjb21wdXRlIChyZWR1Y2VkIHNjaGVtZSkgMQoKLS0gQSBzYW1wbGUgY2FsY3VsYXRpb24gc2NoZW1lCnNjaGVtZSA6OiBGcmFjdGlvbmFsIGEgPT4gW0NvbmRpdGlvbiAoW2FdIC0+IGEpXQpzY2hlbWUgPSBbCiBjb25kQWJzICAgICAgMTAuMDAsCiBjb25kUmVsICAgICAgNS4wMCwKIGNvbmRSZWxCYXNlICAzLjI1LAogY29uZEFicyAgICAgMjAuMDAsCiBjb25kUmVsICAgICAgMy4wMCwKIGNvbmRSZWxCYXNlICAyLjAwLAogY29uZFJlbCAgICAgIDcuMDAsCiBjb25kQWJzICAgICAxMC4wMAogXQoKLS0tIFJlZHVjZWQgc2NoZW1lIGNvbnNpc3RzIG9ubHkgb2YgdGhlIHJlbGF0aXZlIGNvbmRpdGlvbnMKcmVkdWNlZCA6OiBbQ29uZGl0aW9uIGFdIC0+IFtDb25kaXRpb24gYV0KcmVkdWNlZCBzY2hlbWUgPSBmaWx0ZXIgaXNSZWxhdGl2ZSBzY2hlbWUKCgotLSBUZXN0IChzaG91bGQgcmVwcm9kdWNlIHRoZSBpbnB1dCAoMTAwKSApCm1haW4gPSBkbwogICAgcHJpbnQgJCByZXNvbHZlIHNjaGVtZSAkIGNvbXB1dGUgc2NoZW1lIDEwMAo=