Reputation: 53
I'd like a more elegant way to write the following two functions, ideally in one :
applyOperatorBetweenVariableLists:: [Variable] -> String -> [Variable] -> [Variable]
applyOperatorBetweenVariableLists firstList operator secondList = concat $ map (test firstList operator) secondList
test:: [Variable] -> String -> Variable -> [Variable]
test firstVariables operator secondVariable = concat $ map (applyOperatorBetweenVariables secondVariable operator) firstVariables
The declaration of applyOperatorBetweenVariables
is :
applyOperatorBetweenVariables:: Variable -> String -> Variable -> [Variable]
I'm quite sure there must be a Prelude Function that does exactly this, or a very elegant way to write it.
Upvotes: 1
Views: 137
Reputation: 48572
This can be done concisely with a do
block:
applyOperatorBetweenVariableLists firstList operator secondList = do
secondVariable <- secondList
firstVariable <- firstList
applyOperatorBetweenVariables secondVariable operator firstVariable
If you wanted to be even more concise, you could reorder the arguments to both applyOperatorBetweenVariableLists
and applyOperatorBetweenVariables
, and then use either liftJoin2
or bind2
to implement it (like my final sentence below but with it in place of liftA2
).
My original answer was wrong, as it left a layer of nesting (i.e., should have done an extra concat
or join
):
That's almost just liftA2
, but your arguments are in a weird order. Here's how you'd implement what you wrote in terms of that:
import Control.Applicative (liftA2)
applyOperatorBetweenVariableLists firstList operator secondList = liftA2 (flip applyOperatorBetweenVariables operator) secondList firstList
From that definition, it should be clear how you could change and simplify that to applyOperatorBetweenVariableLists = liftA2 . applyOperatorBetweenVariables
just by reordering the arguments to it and to applyOperatorBetweenVariables
.
Upvotes: 1