使用数组解析haskell中的方案向量

时间:2011-06-23 18:05:54

标签: arrays haskell parsec

我正在尝试在48小时内编写自己的方案教程,并且作为haskell的新手,这非常困难。 我正在研究一个问题,我应该添加解析方案向量的能力(第3.4节练习2)。

我正在使用此数据类型:

data LispVal = Atom String                  
         | List [LispVal]                   
         | Vector (Array Int LispVal)

要解析,我正在寻找'#('然后尝试解析向量内容,将它们放入列表并将该列表转换为数组。

我正在尝试使用我已经拥有并正在使用的列表解析函数,但它将方案列表解析为上面的LispVal列表,并且我很难将其恢复到常规列表中。或者至少这就是我认为我的问题。

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

有关如何解决此问题的任何想法? 谢谢, 西蒙

CNC中 这是我得到的编译错误:

  

无法匹配预期类型a -> LispVal' against inferred type Parser LispVal'在第二个参数中   (.)' namely parseList'在第二个   (.)' namely lispValToList的参数。 parseList'在   表达式:listToArray。   lispValToList。 parseList

2 个答案:

答案 0 :(得分:6)

您没有提供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

你可以写一些更紧凑的东西,但这段代码试图自我记录;)

答案 1 :(得分:2)

parseListparser LispVal类型的Monad,而lispValtoList需要一个普通的LispVal:

parseVectorInternals = listToArray . lispValtoList `liftM` parseList

如果你是我8周前读到同一本书的地方,以下内容对你也有帮助:

所有这些行都是等效的:

parseVectorInternals = (listToArray . lispValtoList) `liftM` parseList
parseVectorInternals = liftM (listToArray . lispValtoList) parseList
parseVectorInternals = parseList >>= \listLispVal -> return listToArray (lispValtoList listLispVal)
parseVectorInternals = do 
  listLispVal <- parseList 
  return listToArray (lispValtoList listLispVal)