Как определить переменную на основе оператора if / then / else - PullRequest
5 голосов
/ 24 августа 2010

Я пытаюсь перевести некоторый код на Python на haskell. Однако я дошел до того, что не уверен, что делать дальше.

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

Я пытался перевести это на это:

<code>
if odd length prod
    then ss = countConsonants cust
    else ss = countVowels cust
if  length (cust <code>intersect</code> prod) > 0
    then ss = 1.5 * ss
    else Nothing</p>

<p>return ss

Но я продолжаю получать ошибки:

Ошибка разбора на входе `= '

Любая помощь или слова мудрости по этому вопросу будут с благодарностью.

Ответы [ 6 ]

14 голосов
/ 24 августа 2010

Не думайте о программировании на Haskell как о «если это, то сделайте это, затем сделайте другое» - вся идея , делающая вещи в последовательности , является обязательной. Вы не проверяете условие, а затем определяете переменную - вы просто вычисляете результат, который зависит от условия. В функциональном программировании if является выражением, а переменным присваивается результат выражения, а не присваивается внутри него.

Самый прямой перевод будет:

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
6 голосов
/ 24 августа 2010

В Haskell, if является выражением, а не утверждением.Это означает, что он возвращает значение (например, функцию) вместо выполнения действия.Вот один из способов перевести ваш код:

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

Вот еще один способ:

return if length ( cust intersect prod) > 0 
    then Just $ 1.5 * if odd length prod 
        then countConsinants cust 
        else countVowels cust 
    else Nothing

Как указал Мэтт, ваш код Python не возвращает None.Каждый путь кода устанавливает ss в число.Если это так, как это должно работать, вот перевод на Haskell:

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
3 голосов
/ 24 августа 2010

На вашем месте я бы использовал охранников .Может быть, я язычник из Хаскелла.

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
2 голосов
/ 24 августа 2010

Я бы написал так на Хаскеле:

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

Некоторые комментарии о том, что вы написали:

  • Вы можете выполнять назначения в Haskell, используя синтаксис let и where. В общем, все, что вы пишете на Хаскеле, является выражением. В вашем случае вы должны написать все это как одно выражение, и использование let или where упрощает эту задачу.
  • return в Haskell означает нечто иное, чем в Python, он используется для вычислений с побочными эффектами (например, IO). Для вашего примера в этом нет необходимости.
  • Nothing - это специальное значение типа Maybe a. Этот тип представляет значения типа a с возможной ошибкой (Nothing).

И чтобы ответить на ваш прямой вопрос.
Этот код Python

if b:
  s = 1
else:
  s = 2

будет переведено на Haskell в s = if b then 1 else 2 внутри предложения let или where.

1 голос
/ 24 августа 2010

Чтобы конкретно ответить на ваш вопрос.«ss» уже имеет значение.Просто невозможно дать ему другое значение.ss = ss * 1.5 не имеет смысла.

1 голос
/ 24 августа 2010

Функциональное программирование отличается от императивного программирования.Попытка «перевести» строку за строкой - это не то, как должен использоваться Haskell.

...