TareaHaskell.hs: 36: 69: ошибка: ошибка синтаксического анализа при вводе ')' - PullRequest
0 голосов
/ 06 марта 2019

Я впервые пробую Хаскель. Я пытаюсь сделать функцию, которая берет элемент и список и удаляет второе появление элемента. Например, если элемент 2, а список [2,3,4,2,5,2], результат будет [2, 3, 4, 5, 2].

Однако я получаю эту ошибку:

TareaHaskell.hs:36:69: error: parse error on input ‘)’
   |
36 |     | ( (a == x) && not (isItIn x newList) ) = ( (let newList = x:[]) && (deleteSecond a xs) ) 

Код:

isItIn :: (Eq a ) => a -> [a] -> Bool
isItIn a [] = False
isItIn a (x:xs) = if a == x
                  then True
                  else isItIn a xs

deleteSecond :: (Eq a ) => a -> ( [a] -> [a] )
deleteSecond a [] = newList
deleteSecond a (x:xs)
    | ( (a == x) && not (isItIn x newList) ) = ( (let newList = x:[]) && (deleteSecond a xs) )
    | (a == x) && (isItIn x newList) = (deleteSecond a xs)
    | otherwise = let newList = x:[] && deleteSecond a xs

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

Ответы [ 2 ]

6 голосов
/ 06 марта 2019

Проблема в том, что синтаксический анализатор не ожидает ) в этом коде:

(let newList = x:[])

, поскольку в Haskell недопустимо иметь оператор let, за которым не следует in.(За исключением внутри блока do.)

Мне действительно не ясно, каково ваше истинное намерение, но все, что нужно let - это дать более сложному выражению временное имя внутриблок кода.let оператор без сопровождающего in не имеет никакого смысла и вызывает здесь ошибку вашего разбора.

4 голосов
/ 06 марта 2019

Ваш код немного сложнее. Если вы упростили, было бы более понятно, где проблема, но

let newList = x:[]

действительно только в том случае, если следующий символ - in. Парсер жалуется, что вы пытаетесь заключить его в скобки без причины. Оператор let..in - это просто способ временной привязки имени к значению с целью выражения.

let var = value in expr

Что касается самой проблемы: ее довольно легко решить с помощью явной рекурсии.

removeSecond :: (Eq a) -> [a] -> [a]
removeSecond = go False
  where go _     _      []     = []
        go True  needle (x:xs) | needle == x = xs
                               | otherwise   = x : go True needle xs
        go False needle (x:xs) | needle == x = x : go True needle xs
                               | otherwise   = x : go False needle xs
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...