Functional programming is different from imperative programming. Trying to "translate" line by line isn't how Haskell is meant to be used.
To specifically answer your question. "ss" already has a value. It simply isn't possible to give it a different value. ss = ss * 1.5
makes no sense.
In Haskell, if
is an expression, not a statement. This means it returns a value (like a function) instead of performing an action. Here's one way to translate your code:
ss = if odd length prod
then countConsinants cust
else countVowels cust
return if length ( cust intersect prod) > 0
then Just $ 1.5 * ss
else Nothing
Here's another way:
return if length ( cust intersect prod) > 0
then Just $ 1.5 * if odd length prod
then countConsinants cust
else countVowels cust
else Nothing
As Matt has pointed out, however, your Python code doesn't return None
. Every code path sets ss
to a number. If this is how it's supposed to work, here's a Haskell translation:
let ss = if odd $ length prod
then countConsonants cust
else countVowels cust
in if length (cust `intersect` prod) > 0
then 1.5 * ss
else ss
Don't think of programming in Haskell as "if this, then do that, then do the other thing" — the entire idea of doing things in a sequence is imperative. You're not checking a condition and then defining a variable — you're just calculating a result that depends on a condition. In functional programming, if
is an expression and variables are assigned the result of an expression, not assigned inside it.
The most direct translation would be:
let ss = if odd $ length prod
then countConsonants cust
else countVowels cust
in if length (cust `intersect` prod) > 0
then Just $ 1.5 * ss
else Nothing
I would write it like this in Haskell:
if (not $ null $ cust_factors `intersect` prod_factors)
then ss * 1.5
else ss
where
ss = if (even $ length prod)
then 1.5 * count_vowels cust
else count_cosinants cust
Some comments about what you wrote:
- You can do assignment in Haskell using the
let
andwhere
syntax. In general everything you write in Haskell are expressions. In your case you have to write the whole thing as a single expression and usinglet
orwhere
simplifies that task. return
in Haskell means something different than in Python, it's used for computations with side effects (like IO). For your example there is no need for it.Nothing
is a special value of the typeMaybe a
. This type represents values of typea
with possible failure (theNothing
).
And to answer your direct question.
This Python code
if b:
s = 1
else:
s = 2
would be translated to Haskell to s = if b then 1 else 2
inside a let
or where
clause.
If I were you I'd use guards. Maybe I'm a Haskell heathen.
ss prod prodfactors cust | even $ length prod = extratest . (1.5 *) . countvowels cust
| otherwise = extratest . countconsonants cust
where extratest curval | custfactorsintersection prodfactors > 0 = curval * 1.5
| otherwise = curval