ошибка синтаксического анализа (возможно, неправильный отступ или несовпадающие скобки) — проблема Haskell с основным объявлением

#haskell

#haskell

Вопрос:

Это мой код

 root::(Integer,Integer)->Integer
root guess number   | (guess*guess == number ) =guess
                    | root (guess number/guess)/2 number
main::IO()
main = {print(root 1,4)}
  

Я продолжаю получать ошибку синтаксического анализа (возможно, неправильный отступ или несовпадающие скобки), даже если я не упоминаю оператор print внутри фигурных скобок. Кто-нибудь может мне помочь?

Ответ №1:

Во-первых, у вас, похоже, есть некоторая путаница в отношении объявления и передачи параметров.

Обычно можно выделить два способа (две «традиции», если хотите) передачи параметров — «форма с кортежами» и «форма с карри».

Первая — «кортежная форма» — передает все параметры вместе в кортеже:

 -- Function declaration
root :: (Integer, Integer) -> Integer
root (guess, number) = ...

-- Calling the function
x = root (1, 4)
  

Кортеж обозначается круглыми скобками и разделительными запятыми. Здесь тип параметров — кортеж — (Integer, Integer) , — а формальные параметры сопоставляются как кортеж — (guess, number) , — и при вызове функции я передаю их как кортеж — (1, 4) . Одинаковый синтаксис во всех трех случаях.

Технически эта функция имеет только один параметр, а не два. И этот один параметр имеет тип кортежа.

Последняя — «curried form» — передает параметры «один за другим», так сказать:

 -- Function declaration
root :: Integer -> Integer -> Integer
root guess number = ...

-- Calling the function
x = root 1 4
  

Здесь типы параметров объявляются отдельно в форме curried — Integer -> Integer -> , — и параметры сопоставляются в форме curried — guess number = ... , — и при вызове функции они также передаются в форме curried — 1 4 .


Однако в вашем коде, похоже, присутствует смешение этих двух стилей:

  • Тип root говорит, что параметры кортежируются — (Integer, Integer)
  • В теле root говорится, что они обработаны — root guess number
  • И сайт вызова представляет собой своего рода половину кортежа — есть запятая, но нет круглых скобок.

Выберите один стиль и следуйте ему во всех трех местах.


Во-вторых, два случая в теле root имеют неправильную форму. Каждый случай должен иметь форму | <condition> = <body> . В вашем первом случае у вас есть условие (guess*guess == number) и тело guess , но во втором случае есть только одна часть (нет знака равенства).

Исходя из семантики, я бы рискнул предположить, что ваш второй случай должен был быть «иначе» — т. Е. Он должен был оцениваться, если условие первого случая не соответствовало.

Если это правильно, просто добавьте otherwise как условие:

                 | (guess*guess == number) = guess
                | otherwise = root (guess number/guess)/2 number
  

Комментарии:

1. root (guess number/guess)/2 number синтаксический анализ выполняется как (root (guess number/guess)) / (2 number) , поэтому требуется еще несколько круглых скобок. ( 1)