2014-11-07 2 views
0

интересно, что синтаксически неправильно с этой функцией?Haskell Где Синтаксис

isPrime :: Int -> Bool 
isPrime a = go a (a - 1) 
     where 
     go a b 
     |b == 1 = True 
     |a/b == 0 = False 
     |otherwise = isPrime a (b - 1) 

Просто простую функцию, чтобы определить, является ли число простым или нет, спасибо.

isPrime :: Int -> Bool 
isPrime a = go a (a - 1) 
    where 
     go a b 
      |b == 1 = True 
      |a/b == 0 = False 
      |otherwise = isPrime a (b - 1) 

У меня теперь есть это, но все еще возникают ошибки компиляции?

+0

Вы должны отступа охранников для 'go', чтобы они прошли декларацию' go'. Если вы используете вкладки для отступа, остановитесь, это проблема, которую я вижу на SO очень часто. Просто измените настройки редактора, чтобы вставлять пробелы вместо вкладок. – bheklilr

+0

Причина, по которой я говорю, использовать пробелы над вкладками, заключается в том, что ваш редактор и GHC будут видеть пробелы как одинаковое количество столбцов, но это не обязательно верно для вкладок. GHC просматривает вкладки как фиксированную ширину столбца (я считаю, 8), но большинство людей имеют свой редактор, настроенный на 4 столбца. Также следует упомянуть, что декларация для 'go' должна начинаться после' where', поэтому переключитесь на пробелы, поставьте 4 перед 'where', 8 перед' go a b' и 12 перед каждым защитником. – bheklilr

+0

Спасибо, внесли изменения, которые вы предложили, но все еще возникают проблемы с компиляцией? – user2069328

ответ

1

Программы Haskell должны быть хорошо отступом! То есть, как отступ программы так:

isPrime :: Int -> Bool 
isPrime a = go a (a - 1) 
    where -- indent before `where` 
    go a b -- indent after `where`'s indent 
     | b == 1  = True 
     | a/b == 0 = False 
     | otherwise = isPrime a (b - 1) 

Если вы измените код таким образом, вы все равно получите ошибку при компиляции его. Причина в том, что вы пытаетесь вызвать isPrime с двумя аргументами в теле go, но он принимает только один (это указано в аннотации isPrime). Чтобы отредактировать его, вам просто нужно заменить isPrime a (b - 1) на go a (b - 1).

После этой правки, вы получите другую ошибку при компиляции программы: a заявил, что Int, но вы подаете дробное деление на него с / оператора. Для Int типа только целочисленное деление разрешается:

a `div` b == 0 = False 

Но вам не нужно применять это разделение вообще. Для того, чтобы утверждать, является ли один номер можно разделить на другой, вы должны отдыхать разделения и сравнить его с нуля:

a `mod` b == 0 = False 

Таким образом, окончательная программа будет:

isPrime :: Int -> Bool 
isPrime a = go a (a - 1) 
    where -- indent before `where` 
    go a b -- indent after `where`'s indent 
     | b == 1   = True 
     | a `mod` b == 0 = False 
     | otherwise  = go a (b - 1) 
Смежные вопросы