+1  A: 

Functional programming is different from imperative programming. Trying to "translate" line by line isn't how Haskell is meant to be used.

Turtle
Doesn't answer the questions, but yeah.
delnan
+1  A: 

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.

Turtle
+6  A: 

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
Gabe
Though the answer to the question is right, this isn't well-typed (`*` doesn't have the same type as `Nothing`), and I'm not sure why we'd use `return` here.
Chuck
Chuck: You're right. I tried to show the proper form while minimizing the rewriting because I thought it would make it too hard to figure out what I was trying to demonstrate. Maybe I didn't go far enough, though.
Gabe
Chuck, the original doesn't return nothing if the second test fails, it returns whatever the first test set ss to be. (In Python)
Matt Ellen
I meant that @Gabe. sorry
Matt Ellen
Good point, Matt. It's hard to tell whether the `return` was meant to be indented (as implied by his Haskell attempt) or not (as implied by the actual Python code), so I included a version that always returns a value.
Gabe
+11  A: 

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
Chuck
Chuck, thanks for the translation as well as the explanation. It cleared things up for me.
Bryce
+2  A: 

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 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.

Daniel Velkov
+3  A: 

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
Matt Ellen