Я новичок и для Haskell, и для Parsec. В попытке узнать больше о языке и этой библиотеке, в частности, я пытаюсь создать парсер, который может анализировать Lua сохраненные файлы переменных. В этих файлах переменные могут принимать следующие формы:Проблемы с Parsec Haskell <|> Оператор
VarName = значение
VarName = {значение, значение, ...}
VarName = {{значение, значение}, {значение, значение, ...}}
Я создал парсеры для каждого из этих типов, но когда я их строю вместе с выбором < |> оператор, я получаю ошибку типа.
Couldn't match expected type `[Char]' against inferred type `Char'
Expected type: GenParser Char st [[[Char]]]
Inferred type: GenParser Char st [[Char]]
In the first argument of `try', namely `lList'
In the first argument of `(<|>)', namely `try lList'
Мое предположение (хотя я не могу найти его в документации), что каждый анализатор передается оператору выбор должен возвращать один и тот же тип. Вот код в вопросе:
data Variable = LuaString ([Char], [Char])
| LuaList ([Char], [[Char]])
| NestedLuaList ([Char], [[[Char]]])
deriving (Show)
main:: IO()
main = do
case (parse varName "" "variable = {{1234,\"Josh\"},{123,222}}") of
Left err -> print err
Right xs -> print xs
varName :: GenParser Char st Variable
varName = do{
vName <- (many letter);
eq <- string " = ";
vCon <- try nestList
<|> try lList
<|> varContent;
return (vName, vCon)}
varContent :: GenParser Char st [Char]
varContent = quotedString
<|> many1 letter
<|> many1 digit
quotedString :: GenParser Char st [Char]
quotedString = do{
s1 <- string "\"";
s2 <- varContent;
s3 <- string "\"";
return (s1++s2++s3)}
lList :: GenParser Char st [[Char]]
lList = between (string "{") (string "}") (sepBy varContent (string ","))
nestList :: GenParser Char st [[[Char]]]
nestList = between (string "{") (string "}") (sepBy lList (string ","))
Тип данных Variable предназначен для инкапсуляции имени переменной и содержимого переменной в кортеж. Я вижу из ваших и ответов Martijn, что это не лучший способ действия, потому что мне нужен дополнительный слой абстракции. У меня есть вопрос о вашем ответе: Какая цель - > операторов, работающих в вашем коде? (Я думал, что они просто для сообщений об ошибках). – GraemeFore
Я не использовал '>'. Может быть, вы имеете в виду '<$>'. Это просто сокращенная информация для 'fmap', поэтому' LuaString <$> идентификатор' означает «разобрать идентификатор», а затем обернуть результат с помощью функции «LuaString». – luqui
Yikes! Прекрасный пример того, почему вы не должны публиковать вопросы в течение всего времени. Еще раз спасибо. – GraemeFore