Contribution:
haskellLogging
Headline
Logging in Haskell with non-monadic code
Characteristics
Starting from a straightforward family of functions for cutting salaries, the concern of logging the salary changes is incorporated into the functions such that the function results are enriched by the log entries for salary changes. This code is relatively verbose and implies poor abstraction. In particular, functionality for composing logs is scattered all over the functions. Ultimately, such a problem must be addressed with monads.
Illustration
Salary changes can be tracked in logs as follows:
type Log = [LogEntry]
data LogEntry =
LogEntry {
name :: String,
oldSalary :: Float,
newSalary :: Float
}
deriving (Show)
Here are a few entries resulting from a salary cut for the sample company:
[LogEntry {name = "Craig", oldSalary = 123456.0, newSalary = 61728.0},
LogEntry {name = "Erik", oldSalary = 12345.0, newSalary = 6172.5},
LogEntry {name = "Ralf", oldSalary = 1234.0, newSalary = 617.0},
LogEntry {name = "Ray", oldSalary = 234567.0, newSalary = 117283.5},
LogEntry {name = "Klaus", oldSalary = 23456.0, newSalary = 11728.0},
LogEntry {name = "Karl", oldSalary = 2345.0, newSalary = 1172.5},
LogEntry {name = "Joe", oldSalary = 2344.0, newSalary = 1172.0}]
Given a log, the median of salary deltas can be computed as follows:
log2median :: Log -> Float
log2median = median . log2deltas
log2deltas :: Log -> [Float]
log2deltas = sort . map delta
where
delta entry = newSalary entry - oldSalary entry
The above log reduces to the following median:
-6172.5
Feature:Cut is implemented in logging-enabled fashion as follows:
cut :: Company -> (Company, Log)
cut (Company n ds) = (Company n ds', log)
where
(ds', logs) = unzip (map cutD ds)
log = concat logs
cutD :: Department -> (Department, Log)
cutD (Department n m ds es)
= (Department n m' ds' es', log)
where
(m',log1) = cutE m
(ds', logs2) = unzip (map cutD ds)
(es', logs3) = unzip (map cutE es)
log = concat ([log1]++logs2++logs3)
cutE :: Employee -> (Employee, Log)
cutE (Employee n a s) = (e', log)
where
e' = Employee n a s'
s' = s/2
log = [ LogEntry {
name = n,
oldSalary = s,
newSalary = s'
} ]
Thus, all functions return a regular data item (i.e., some part of the company) and a corresponding log. When lists of company parts are processed with map, then the lists of results must be unzipped (to go from a list of pairs to a pair of lists). In the function for departments, multiple logs arise for parts a department; these intermediate logs must be composed.
Relationships
- See Contribution:haskellComposition for the corresponding contribution that does not yet involve logging. The data model is preserved in the present contribution, but the functions for cutting salaries had to be rewritten since the logging concern crosscuts the function.
- See Contribution:haskellWriter for a variation on the present contribution, which leverages a writer monad, though, for conciseness and proper abstraction.
Architecture
There are these Haskell modules:
- Company.hs: the data model reused from Contribution:haskellComposition.
- Cut.hs: the combined implementation of Feature:Cut and Feature:Logging.
- Log.hs: types and functions for logs of salary changes needed for Feature:Logging.
- Main.hs: demonstration of all functions.
User contributions
User edits
Syntax for editing wiki
For you are available next options:will make text bold.
will make text italic.
will make text underlined.
will make text striked.
will allow you to paste code headline into the page.
will allow you to link into the page.
will allow you to paste code with syntax highlight into the page. You will need to define used programming language.
will allow you to paste image into the page.
is list with bullets.
is list with numbers.
will allow your to insert slideshare presentation into the page. You need to copy link to presentation and insert it as parameter in this tag.
will allow your to insert youtube video into the page. You need to copy link to youtube page with video and insert it as parameter in this tag.
will allow your to insert code snippets from @worker.
Syntax for editing wiki
For you are available next options:will make text bold.
will make text italic.
will make text underlined.
will make text striked.
will allow you to paste code headline into the page.
will allow you to link into the page.
will allow you to paste code with syntax highlight into the page. You will need to define used programming language.
will allow you to paste image into the page.
is list with bullets.
is list with numbers.
will allow your to insert slideshare presentation into the page. You need to copy link to presentation and insert it as parameter in this tag.
will allow your to insert youtube video into the page. You need to copy link to youtube page with video and insert it as parameter in this tag.
will allow your to insert code snippets from @worker.