Suppose we have a sampleBy function that selects items from a list of pairs based on the second element value and then returns the selected first values. It takes a function of all the second values and returns their indices in the original list. This can be implemented as below:
-- lookup a value in a vector by index
at :: [a] -> Int -> a
fst :: (a, b) -> a
snd :: (a, b) -> b
map :: (a -> b) -> [a] -> [b]
The sampleBy implementation looks nice, however, when the code is generated, the map fst xs expression is re-evaluated at every index lookup. I want to force it to be evaluated only once. I can rewrite the expression as:
sampleBy f xs = map (at labels) (f (map snd xs)) where
labels = map fst xs
But this evaluates to exactly the same code again, with labels being substituted into the main expression.
What would be nice is a means to force order of evaluation. Perhaps with let syntax?
sampleBy f xs =
let labels = map fst xs
let data = map snd xs
map (at labels) (f data)
Where the compiler guarantees labels will be evaluated just once before the main expression. Adding let is a pretty major change.
Alternatively, we could define let as a source functions that forces evaluation:
let :: a -> (a -> b) -> b
This approach may serve as workaround until we implement real let handling.
Suppose we have a
sampleBy
function that selects items from a list of pairs based on the second element value and then returns the selected first values. It takes a function of all the second values and returns their indices in the original list. This can be implemented as below:Where
The
sampleBy
implementation looks nice, however, when the code is generated, themap fst xs
expression is re-evaluated at every index lookup. I want to force it to be evaluated only once. I can rewrite the expression as:But this evaluates to exactly the same code again, with
labels
being substituted into the main expression.What would be nice is a means to force order of evaluation. Perhaps with
let
syntax?Where the compiler guarantees
labels
will be evaluated just once before the main expression. Addinglet
is a pretty major change.Alternatively, we could define
let
as a source functions that forces evaluation:This approach may serve as workaround until we implement real
let
handling.