Доброго времени суток!
Есть такой код:
isChar :: Char -> Bool
isChar c = (c /= '|') && (c /= '*') && (c /= '(') && (c /= ')')
data Tree a = Empty | Leaf a | Node (Tree a) (Tree a) (Tree a)
deriving (Eq, Show)
rep :: Parser Char (Tree Char)
rep = expr
where expr = term <*> rest_expr <@ (\(t, r) -> r t)
rest_expr :: Parser Char (Tree Char -> Tree Char)
rest_expr = (sym_or *> term <@ (flip re_or)) <*> rest_expr <@ (\(n, r) -> r . n) <|> f_epsilon
term :: Parser Char (Tree Char)
term = sqn <*> rest_term <@ (\(s, t) -> t s)
rest_term :: Parser Char (Tree Char -> Tree Char)
rest_term = sqn <*> rest_term <@ (\(s, t) -> t . ((flip re_cat) s)) <|> f_epsilon
sqn :: Parser Char (Tree Char)
sqn = factor <*> opt_many <@ (\(f, o) -> o f)
opt_many :: Parser Char (Tree Char -> Tree Char)
opt_many = sym_any <@ (\_ -> re_any) <|> f_epsilon
factor :: Parser Char (Tree Char)
factor = letter <|> (parenthesized expr)
letter :: Parser Char (Tree Char)
letter = satisfy isChar <@ re_sym
sym_any = symbol '*'
sym_or = symbol '|'
f_epsilon :: Parser Char (b -> b)
f_epsilon = epsilon <@ (\_ -> id)
re_sym s = Node (Leaf s) Empty Empty
re_cat r s = Node r s Empty
re_or r s = Node r (Leaf '|') s
re_any s = Node s (Leaf '*') Empty
Он работает. Определения использованных нестандартных функций (типа <*>) есть тут: http://ru.wikibooks.org/wiki/%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0
%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%BF%D0%B0%D1%80%D1%81%D0%B5%D1%80%D1%8B
Хочу обобщить функцию rep, параметризировав ее функциями re_sym,
re_cat, re_or re_any:
rep :: (Char -> a) -> (a -> a -> a) -> (a -> a -> a) -> (a -> a) -> Parser Char a
rep re_sym re_cat re_or re_any = expr
where expr = term <*> rest_expr <@ (\(t, r) -> r t)
rest_expr :: Parser Char (a -> a)
rest_expr = (sym_or *> term <@ (flip re_or)) <*> rest_expr <@ (\(n, r) -> r . n) <|> f_epsilon
term :: Parser Char a
term = sqn <*> rest_term <@ (\(s, t) -> t s)
rest_term :: Parser Char (a -> a)
rest_term = sqn <*> rest_term <@ (\(s, t) -> t . ((flip re_cat) s)) <|> f_epsilon
sqn :: Parser Char a
sqn = factor <*> opt_many <@ (\(f, o) -> o f)
opt_many :: Parser Char (a -> a)
opt_many = sym_any <@ (\_ -> re_any) <|> f_epsilon
factor :: Parser Char a
factor = letter <|> (parenthesized expr)
letter :: Parser Char a
letter = satisfy isChar <@ re_sym
sym_any = symbol '*'
sym_or = symbol '|'
f_epsilon :: Parser Char (b -> b)
f_epsilon = epsilon <@ (\_ -> id)
Такой код не работает, Hugs выдает:
ERROR "lex_analyze.hs":117 - Inferred type is not general enough
*** Expression : letter
*** Expected type : Parser Char a
*** Inferred type : Parser Char _5
Если убрать объявления типов локальных определений, то все работает. Почему так происходит?
Ответ на:
комментарий
от Miguel
Ответ на:
комментарий
от anonymous
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.
Похожие темы
- Форум C / Базовые типы / 100 вопросов (2008)
- Форум Типизация в Хаскеле - вопрос (2007)
- Форум Хаскель (2007)
- Форум Миры хаскеля (2014)
- Форум негодный Хаскель (2008)
- Форум хаскель, книга (2007)
- Форум Хаскель плох (+) (2008)
- Форум ОБЪЯВЛЕНИЕ (2024)
- Форум Объявление! (2018)
- Форум Объявление (2014)