Программа OCaml для определения простого числа - PullRequest
0 голосов
/ 17 сентября 2018

Я пытаюсь написать программу на языке OCaml, но у меня возникают проблемы с использованием вложенных функций. Вот код, который я написал:

let prime : int -> bool
= fun x ->
  if x > 2 then
    let a = x - 1 in
      let rec checkZero a x =
        if a > 1 then
          match x mod a with
           0 -> false
          |_ -> checkZero (a - 1) x
        else if a = 1 then
          true
  else if x = 2 then
    true
  else
    false
;;

Чтобы кратко объяснить мой код, я использую вложенную функцию с именем checkZero, чтобы определить, делится ли x на значение a, которое начинается с x - 1 и снижается до 2.

После выполнения сопоставления с образцом, если результат операции mod равен 0, тогда x не является простым числом, а если результатом является что-либо еще, то мы вычитаем 1 из a и выполняем checkZero еще раз.

Конкретное сообщение об ошибке, которое я получаю, заключается в том, что я получаю синтаксическую ошибку, где двойные точки с запятой.

Я не слишком знаком с тем, как работает OCaml, но я знаю, что двойные точки с запятой используются, когда вы хотите, чтобы весь код был выражением. Я не совсем уверен, что является причиной ошибки.

Любые отзывы приветствуются. Спасибо!

Ответы [ 2 ]

0 голосов
/ 17 апреля 2019

Для дальнейшего использования, вот более простая функция, которая работает так же, как ваша (без оптимизации, но короче):

let prime n =
    let rec checkZero x d = match d with
        | 1 -> true    
        | _ -> (x mod d <> 0) && checkZero x (d-1)
    in match n with
    | 0 | 1 -> false
    | _ -> checkZero n (n-1) ;;
0 голосов
/ 17 сентября 2018

Я понял эту проблему и теперь чувствую себя довольно глупо, когда увидел ее. Надеюсь, это поможет всем, кто борется с подобными проблемами.

Как сказал @glennsl в комментарии к вопросу, я упустил одну вещь: «let ... in должно сопровождаться выражением, которое его вызывает». Проблема с моим кодом в том, что функция checkZero не работала так, как я планировала, из-за отсутствия вызова.

Еще одна вещь, которую я понял, заключается в том, что вместо использования операторов if ... then ... else ... иногда удобнее выполнять сопоставление с образцом.

Вот код, который я придумал, который работает (если в коде есть какие-либо ошибки, пожалуйста, дайте мне знать):

let prime : int -> bool
= fun x ->
  match x with
     0 -> false
   | 1 -> false
   | _ -> let a = (x - 1) in
            let rec checkZero a x =
              if (a > 1) then
                match x mod a with
                   0 -> false
                 | _ -> checkZero (a - 1) x
              else
                true
              in
              checkZero a x
;;

Эквивалентная версия без использования условных операторов:

let prime : int -> bool
= fun n ->
  match n with
     0 -> false
   | 1 -> false
   | _ -> let a = (n - 1) in
            let rec checkZero a n =
              match a with
                 1 -> true
               | _ -> match n mod a with
                         0 -> false
                       | _ -> checkZero (a - 1) n
              in
              checkZero a n
;;
...