Haskell “Prelude.read:无解析”,自己的数据类型

Haskell “Prelude.read:无解析”,自己的数据类型,haskell,haskell-prelude,Haskell,Haskell Prelude,我试图从文件中读取两个自己的数据类型“BoardEdge”的列表。当我尝试运行代码时,出现异常: Main.hs:Prelude.read:无解析 因为我怀疑我在负责验证输入validateInput的函数中得到了这个。当我在ghci中尝试插入两个BoardEdge“对象”时,该函数运行良好,并为True 有人能给我一些建议吗?我做错了什么?我该如何解决这个问题 数据类型: data Field = Empty | Black | Yellow deriving (Eq, Ord, Enum,

我试图从文件中读取两个自己的数据类型“BoardEdge”的列表。当我尝试运行代码时,出现异常:

Main.hs:Prelude.read:无解析

因为我怀疑我在负责验证输入validateInput的函数中得到了这个。当我在ghci中尝试插入两个BoardEdge“对象”时,该函数运行良好,并为True

有人能给我一些建议吗?我做错了什么?我该如何解决这个问题

数据类型:

data Field = Empty | Black | Yellow deriving (Eq, Ord, Enum, Show, Read)

data BoardEdge = BoardEdge { colRow :: [[(Field, Int)]]} deriving (Read, Eq, Ord, Show) 
Main.hs

    main :: IO()
    main = do
      args <- getArgs
      input <- loadInput args
      putStrLn "Puzzle input loaded:"
      putStrLn input
      let parsedInput = parseInput input
      if (validateInput parsedInput)
        then putStrLn "Input is valid."
        else error "Input invalid!"

    -- asks for path and reads input file
    loadInput :: [String] -> IO String
    loadInput [] =  getPath >>= readFile where
      getPath = do
        putStrLn "Provide path to puzzle input file:"
        getLine
    loadDefinition (a:_) = readFile a


    -- get valid data from input file
    parseInput :: String -> (B.BoardEdge,B.BoardEdge)
    parseInput d = parseInput' $ lines d where
      parseInput' (columns: rows :_) =
        (read columns, read rows)
我的输入文件如下所示:

    [[(Black,2),(Yellow,2),(Black,1)],[(Black,2),(Yellow,1),(Black,3)]]
    [[(Black,5)],[(Black,2),(Black,1)],[(Black,2),(Black,2)],[(Black,1),(Black,2)]]

将您自己的代码片段和Fyodor的注释粘在一起:

Prelude> data Field = Empty | Black | Yellow deriving (Eq, Ord, Enum, Show, Read)
Prelude> data BoardEdge = BoardEdge { colRow :: [[(Field, Int)]]} deriving (Read, Eq, Ord, Show)
Prelude> let edge1 = BoardEdge [[(Black,2),(Yellow,2),(Black,1)],[(Black,2),(Yellow,1),(Black,3)]]
Prelude> show edge1
"BoardEdge {colRow = [[(Black,2),(Yellow,2),(Black,1)],[(Black,2),(Yellow,1),(Black,3)]]}"
Prelude> let correctInput = it -- ^^ the above
所以现在我们知道了里德的期望,也就是这个节目所产生的。这与您用作输入的内容相比如何

Prelude> let myInput =     "[[(Black,2),(Yellow,2),(Black,1)],[(Black,2),(Yellow,1),(Black,3)]]"
Prelude> correctInput == myInput
False

或者不那么刺耳:如果您希望默认读取实例解析您的输入,那么您的输入必须是正确的Haskell代码,带有数据构造函数和所有。在这种情况下,需要使用BoardEdge。

嗯。。。你的拼图输入文件里有什么?谢谢你提醒我!在我的输入文件中,我有两个长长的列表,其中包括Board edge数据类型:[[Field,Int]]。它是这样的:[[Black,2,Yellow,2,Black,1],[Black,2,Yellow,1,Black,3][[Black,2,Yellow,2,Black,1],[Black,2,Yellow,1,Black,3]]这里有一个提示:打开GHCi并尝试显示一些数据结构。您看到的是自动派生读取所期望的格式。因此我现在尝试这样做,对于“show Field”,它表示数据构造函数不在范围内:Field::对于“show B.BoardEdge”,它表示show[[B.Field,Int]]没有实例->B.BoardEdge。创建一个实例可以解决我的问题?@ukaszNiewiński您只能显示您的数据类型的完整值。例如,BoardEdge需要一个colRow。伙计,非常感谢!!您准确地显示了我缺少的内容。我没有想到使用BoardEdge{colRow=[…])。您的比较非常棒,谢谢!:
Prelude> let myInput =     "[[(Black,2),(Yellow,2),(Black,1)],[(Black,2),(Yellow,1),(Black,3)]]"
Prelude> correctInput == myInput
False