Ошибка синтаксического анализа при использовании выражения case внутри guards haskell

#parsing #haskell #functional-programming #syntax-error #case

#синтаксический анализ #haskell #функциональное программирование #синтаксическая ошибка #случай

Вопрос:

Я новичок в Haskell, и у меня возникли проблемы с синтаксисом. То, что я хочу сделать, это предоставить данные и дерево этого типа данных, найти путь к соответствующему узлу в дереве. Я считаю, что моя логика для функции верна, но я не уверен, как сделать ее действительной на Haskell. Я попытался изменить табуляцию на пробелы.

 -- | Binary trees with nodes labeled by values of an arbitrary type.
data Tree a
   = Node a (Tree a) (Tree a)
   | End
  deriving (Eq,Show)

-- | One step in a path, indicating whether to follow the left subtree (L)
--   or the right subtree (R).
data Step = L | R
  deriving (Eq,Show)

-- | A path is a sequence of steps. Each node in a binary tree can be
--   identified by a path, indicating how to move down the tree starting
--   from the root.
type Path = [Step]
pathTo :: Eq a => a -> Tree a -> Maybe Path
pathTo a End = Nothing
pathTo a (Node b l r)
    | a == b = Just []
    | case (pathTo a l) of
                Just p  -> Just [L:p]
                Nothing -> case (pathTo a r) of
                                    Just p  -> Just [R:p]
                                    Nothing -> Nothing
 

Это ошибка:

   parse error (possibly incorrect indentation or mismatched brackets)
 

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

1. это не похоже на guard, вам нужно otherwise = ...

2. Это не похоже на ошибку синтаксического анализа, ваш тип неверен.

3. Ваше редактирование сделало ответ не связанным с вопросом. Если у вас есть дополнительный вопрос, отправьте новый вопрос.

Ответ №1:

Основная проблема здесь заключается в том, что это не похоже на guard: guard — это выражение с типом Bool , это определяет, срабатывает ли guard «срабатывает» или нет. Здесь это, вероятно, `в противном случае:

 pathTo :: Eq a => a -> Tree a -> Maybe Path
pathTo a End = Nothing
pathTo a (Node b l r)
    | a == b = Just []
    | otherwise = case (pathTo a l) of
                Just p  -> Just (L:p)
                Nothing -> case (pathTo a r) of
                                    Just p  -> Just (R:p)
                                    Nothing -> Nothing 

Это также выявило некоторые дополнительные ошибки: Just [L:p] is a Maybe [[Step]] , который вы, вероятно, хотели использовать Just (L:p) , то же самое относится и к Just [R:p] .

Кроме того, вам не нужно использовать вложенные case s, вы можете работать с Alternative typeclass:

 import Control.Applicative((<|>))

pathTo :: Eq a => a -> Tree a -> Maybe Path
pathTo a End = Nothing
pathTo a (Node b l r)
    | a == b = Just []
    | otherwise = ((L:) <

gt; pathTo a l) <|> ((R🙂 <


gt; pathTo a r)

Здесь x <|> y будет приниматься x , если это a Just … , и y в противном случае. Мы используем (L:) <$> … для добавления списка, заключенного в конструктор Just данных, или возврата Nothing в случае is Nothing .