5

Write Yourself a Scheme in 48 Hours チュートリアルを試みていますが、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

これを修正する方法についてのアイデアはありますか? ありがとう、サイモン

-編集-これが私が得るコンパイルエラーです:

予想される型と一致しませんでしたa -> LispVal' against inferred typeParser LispVal' parseList の 2 番目の引数 (.)' namely' の 2 番目の引数(.)' namely lispValToList 内。parseList' 式内: listToArray 。lispValToList . parseList

4

2 に答える 2

6

あなたは提供しませんlispValtoListが、次のタイプがあると思います

lispValtoList :: LispVal -> [LispVal]

parseListこれは、コンパイラがそれが typeであると考えるように示唆しますa -> LispVal。しかし、そうではないのでParser LispVal、のようなものP String -> [(LispVal,String)]です。

LispValリストに入れる前に、解析された値を抽出する必要があります。したがってparseVectorInternals、おそらく次のように見える必要があります

parseVectorInternals = do parsedList <- parseList 
                          let listOfLispVal = lispValtoList parsedList
                          return $ listToArray listOfLispVal

もっとコンパクトなものを書くこともできますが、このコードは自己文書化しようとしています;)

于 2011-06-23T19:12:04.813 に答える
2

parseListは型のモナドですがparser LispVal、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)
于 2011-06-24T05:55:39.070 に答える