I have the following function that convert a list of counts to a discrete probability density function:
freq2prob l = [ (curr / (sum l))) | curr <- l ]
Unfortunately (sum l)
is computed for each of the l
elements making the computational complexity unnecessarily high.
What is the most concise, elegant, "haskellic" way to deal with this?
It's simple:
freq2prob l = [ curr / s | let s = sum l, curr <- l ]
you can put it outside the list comprehension as well: freq2prob l = let s = sum l in [ curr / s | curr <- l ]
(notice the in
). This is effectively the same computation.
That is because the first is essentially translated into
freq2prob :: (Fractional a) => [a] -> [a]
freq2prob l = [ curr / s | let s = sum l, curr <- l ]
= do
let s = sum l
curr <- l
return (curr / s)
= let s=sum l in
l >>= (\curr -> [curr / s])
-- concatMap (\curr -> [curr / s]) l
-- map (\curr -> curr / s) l
and the second, obviously, to the same code,
freq2prob l = let s = sum l in [ curr / s | curr <- l ]
= let s = sum l in
do
curr <- l
return (curr / s)
= let s=sum l in
l >>= (\curr -> [curr / s])