2017-02-01 4 views
0

Это мой первый раз попав в более «академические» языки программирования. Исходя из земли Java/C, у меня возникают некоторые проблемы с операторами If в Haskell. Кажется, что все примеры используют один аргумент и простые gt, ls или eq для сравнения.Haskell If Statement Condition

Что я пытаюсь сделать, это проверить, является ли аргумент функции четным или нечетным, а затем вернуть значение, основанное на этом результате. Это позволяет ускорить вычисление экспоненты, как:

п^к = (п^(к/2))^2, если к четно

п^к = п * п^(K-1), если к нечетно

Вот что я до сих пор:

fastExp1 :: Integer -> Integer 
fastExp1 x y = 
    if y `mod` 2 = 1 
     then x * x^(y-1) 
    else if y `mod` 2 = 0 
     then (x^(y/2))^2 
    else 0 

Я пытался построить его с помощью охраняемых уравнений, но я просто не могу показаться, чтобы получить мой голову вокруг, как его построить:

fastExp2 :: Integer -> Integer 
fastExp2 x y | (x `mod` 1) = 0  = (x^(y/2))^2 
      | (x `mod` 1) = 1  = x * x^(y-1) 
      | otherwise = 0 

В Java, это на самом деле не любой вопрос:

public static int fastExp1 (int x, int y) { 
    if (y%2 == 0) { 
     // The exponent was even. 
     return (int) Math.pow((Math.pow(x,(y/2))), 2); 
    } else if (y%2 == 1) { 
     // The exponent was odd. 
     return (int) Math.pow((x*x), (y-1)); 
    } else { 
     return 0; 
    } 
} 

Я могу подтвердить, что код Java работает, как задумано, но с Haskell я получаю:

C: \ hello.hs: 16: 5:

ошибка синтаксического анализа в случае утверждение: отсутствует обязательное то и еще пункты

Ошибка, модули загружены: нет.

+0

Подсказка 1: почему бы вам не написать 'if (y% 2 = 0) {...}' в Java? - Подсказка 2: 1 ≠ 0 - Подсказка 3: есть причина, по которой вам нужно, чтобы целое число выполнялось на Java. Как бы то ни было, вам нужно, чтобы в Haskell (хотя вы могли бы изменить алгоритм, чтобы это не было необходимо). – leftaroundabout

+0

Является ли 'x \' mod \ '1' опечаткой? – chepner

+3

Оператор равенства - '==', а не '='. – chepner

ответ

2

Как было отмечено в комментариях (chepner & Ben), Haskell использует == для сравнения, где в качестве = используется для определения.

Для будущих читателей, здесь завершенный код:

fastExp1 :: Integer -> Integer -> Integer 
fastExp1 x y = 
    if y `mod` 2 == 1 
     then x * x^(y-1) 
     else if y `mod` 2 == 0 
     then (x^(y `div` 2))^2 
    else 0 

fastExp2 :: Integer -> Integer -> Integer 
fastExp2 x y | (y `mod` 2 == 0)  = (x^(y `div` 2))^2 
      | (y `mod` 2 == 1)  = x * x^(y-1) 
      | otherwise = 0 

Как было предложено leftaroundabout, fastExp2 также может быть сделан:

fastExp2 x y | (y',0) <- y`divMod`2 = (x^y')^2 
      | otherwise = x * x^(y-1) 
+1

И вот как это лучше написано: '' fastExp2 x y | (y ', 0) <- y'divMod'2 = (x^y')^2''' | в противном случае = x * x^(y-1) '. – leftaroundabout

+0

@leftaroundabout Я должен был правильно отформатировать, скажите, если я ошибаюсь. –

+1

В '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '. Однако для людей отступы 'else 0' совпадают с первым' if' выглядит ошибочным, поскольку это 'else' для второго' if'. Я бы отложил такую ​​цепочку 'if/then/else' на том же уровне. – chi