Haskell を使用する関数型プログラミングの入門コースを受講しています。演習の一部は、入力文字列のパーサーを作成することです。
ただし、次のエラーを解決することも、実際に何が起こっているのかを理解することもできません。
Parser.hs:29:71:
Couldn't match expected type `String' with actual type `Char'
In the first argument of `readPoint', namely `start'
In the expression: readPoint start
In the expression:
(readLines track, readPoint start, readLine finish)
エラーは次の行から発生します。
readTrack str = parseTrack (lines str) where
parseTrack (start : finish : track) = (readLines track, readPoint start, readLine finish)
私が予想していたのは、入力文字列が行のリストに分割され、それが parseTrack に渡されることです。次に、parseTrack はパターン マッチングを使用して、リストの上位 2 つの文字列 (行) と残りの文字列に名前を付けます。
しかし、私が信じているのは、finish がリストの一番上の要素であり、start がその文字列の一番上の char に割り当てられるということです。
この問題を解決する方法と、実際に何が起こっているのかを知りたいです。
どうもありがとう!
Parser.hs
module Parser where
import Types
readFloat :: String -> Float
readFloat str = case reads str of
[] -> error "not a floating point number"
(p,_):_ -> p
readInt :: String -> Int
readInt str = case reads str of
[] -> error "not an integer"
(p,_):_ -> p
readPoint :: String -> Point
readPoint str = parsePoint (words str) where
parsePoint (x : y : _) = (readInt x, readInt y)
readLine :: String -> Line
readLine str = parseLine (words str) where
parseLine (x1 : y1 : x2 : y2 : _) = ((readInt x1, readInt y1), (readInt x2, readInt y2))
readLines :: String -> [Line]
readLines str = parseLines (lines str) where
parseLines (line : rest) = readLine line : parseLines rest
readTrack :: String -> Track
readTrack str = parseTrack (lines str) where
parseTrack (start : finish : track) = (readLines track, readPoint start, readLine finish)
Types.hs
module Types where
type Vector2D = (Int, Int)
type Point = Vector2D
type Line = (Point, Point)
type Velocity = Vector2D
type CarState = (Position, Velocity)
type Position = Vector2D
type Trace = [Position]
type Track = ([Line], Point, Line)