fork(1) download
  1. -- Apply a pricing procedure = a list of percentual or absolute additions
  2. -- forwards ("compute")
  3. -- and backwards ("resolve" - which is the point here).
  4.  
  5. -- Each condition is a linear function on any of the formerly computed,
  6. -- intermediate terms, so a condition is a function [a] -> a
  7.  
  8. percent p x = p * x / 100
  9.  
  10. -- Need a data type for conditions,
  11. -- in order to distinguish absolute from relative conditions
  12. data Condition a = RelativeCondition { apply :: a }
  13. | AbsoluteCondition { apply :: a }
  14.  
  15. -- predicate function for detecting relative types
  16. isRelative :: Condition a -> Bool
  17. isRelative( RelativeCondition _ ) = True
  18. isRelative( _ ) = False
  19.  
  20. condRel p = RelativeCondition (\ x -> percent p ( last x ) )
  21. condRelBase p = RelativeCondition (\ x -> percent p ( head x ) )
  22. condAbs q = AbsoluteCondition (\ x -> q )
  23.  
  24. -- How to compute a scheme:
  25. -- Apply functions successively, starting with base price
  26. compute scheme base = last (
  27. foldl (\ x f -> x ++ [ last x + apply f x ] )
  28. [ base ]
  29. scheme
  30. )
  31.  
  32. --- Reduced scheme consists only of the relative conditions
  33. reduced scheme = filter isRelative scheme
  34.  
  35. -- How to resolve a scheme
  36. resolve scheme result =
  37. ( result - compute scheme 0 )
  38. / compute (reduced scheme) 1
  39.  
  40.  
  41. -- A sample calculation scheme
  42. scheme = [
  43. condAbs 10.00,
  44. condRel 5.00,
  45. condRelBase 3.25,
  46. condAbs 20.00,
  47. condRel 3.00,
  48. condRelBase 2.00,
  49. condRel 7.00,
  50. condAbs 10.00
  51. ]
  52.  
  53. -- Test (should reproduce the input (100) )
  54. main = do
  55. print( resolve scheme ( compute scheme 100 ) )
Success #stdin #stdout 0s 6308KB
stdin
Standard input is empty
stdout
100.0