Reputation: 320
I'm trying to translate some python code to haskell. However I reached a point where I'm not sure how to proceed.
if len(prod) % 2 == 0:
ss = float(1.5 * count_vowels(cust))
else:
ss = float(count_consonants(cust)) # muliplicaton by 1 is implied.
if len(cust_factors.intersection(prod_factors)) > 0:
ss *= 1.5
return ss
I've tried to translate it to this:
if odd length prod
then ss = countConsonants cust
else ss = countVowels cust
if length (cust intersect
prod) > 0
then ss = 1.5 * ss
else Nothing
return ss
But I keep getting errors of:
parse error on input `='
Any help or words of wisdom on this would be greatly appreciated.
Upvotes: 5
Views: 5720
Reputation: 11612
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
Upvotes: 4
Reputation: 86838
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
Upvotes: 6
Reputation: 27639
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:
let
and where
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 using let
or where
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 type Maybe a
. This type represents values of type a
with possible failure (the Nothing
).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.
Upvotes: 3
Reputation: 237110
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
Upvotes: 14
Reputation: 1350
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.
Upvotes: 1
Reputation: 1350
Functional programming is different from imperative programming. Trying to "translate" line by line isn't how Haskell is meant to be used.
Upvotes: 1