Доброго времени суток! Есть такой код: 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)
- Форум Хаскель плох (+) (2008)
- Форум хаскель, книга (2007)
- Форум Объявление (2014)
- Форум ОБЪЯВЛЕНИЕ (2024)
- Форум Объявление! (2018)