我正在尝试“在48小时内编写自己的计划”教程,而作为一个新手,这非常困难。
我目前正在研究一个应该添加解析方案 vector 的功能的问题(第3.4节练习2)。
我正在使用此数据类型:
data LispVal = Atom String
| List [LispVal]
| Vector (Array Int LispVal)
为了解析,我正在寻找'#(',然后尝试解析 vector 内容,将它们放入列表中并将该列表转换为数组。
我正在尝试使用已经拥有并且正在使用的列表解析功能,但是它会将方案列表解析到上面的LispVal List中,并且很难将其返回到常规列表中。至少我认为这就是我的问题。
lispValtoList :: LispVal -> [LispVal]
lispValtoList (List [a]) = [a]
parseVector :: Parser LispVal
parseVector = do string "#("
vecArray <- parseVectorInternals
char ')'
return $ Vector vecArray
parseVectorInternals :: Parser (Array Int LispVal)
parseVectorInternals = listToArray . lispValtoList . parseList
listToArray :: [a] -> Array Int a
listToArray xs = listArray (0,l-1) xs
where l = length xs
这是列表解析器:
parseList :: Parser LispVal
parseList = liftM List $ sepBy parseExpr spaces
有想法该怎么解决这个吗?
谢谢,
西蒙
-编辑-
这是我得到的编译错误:
无法匹配预期的类型
a -> LispVal' against inferred type
Parser LispVal'(.)' namely
parseList'在第二个(.)' namely
lispValToList的参数。 parseList”表达式:listToArray。
lispValToList。 parseList
最佳答案
您没有提供lispValtoList
,但我想它具有以下类型
lispValtoList :: LispVal -> [LispVal]
这将建议编译器认为
parseList
是a -> LispVal
类型。但这不是因为它是Parser LispVal
,而是P String -> [(LispVal,String)]
之类的东西。您必须先提取已解析的
LispVal
值,然后才能将其放入列表中。所以
parseVectorInternals
可能看起来像parseVectorInternals = do parsedList <- parseList
let listOfLispVal = lispValtoList parsedList
return $ listToArray listOfLispVal
您可以写一些更紧凑的东西,但是这段代码会尝试自我记录下来;)