#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
, если это aJust …
, иy
в противном случае. Мы используем(L:) <$> …
для добавления списка, заключенного в конструкторJust
данных, или возвратаNothing
в случае…
isNothing
.