读实例导致解析错误 [英] read instance causes parse error
问题描述
我想实现一个读取实例,使我能够读取一个字符串(例如: - - 8 - 3 - )并构建一个包含这些值的列表。
数据值a = Nul | Val a
showsValue ::(Show a)=>值a - > ShowS
showsValue(Val x)=(Value++)。显示x
showsValue(Nul)=(Nothing 0++)
实例显示a =>显示(值a)其中
显示Prec _ x =显示值x
实例读取a =>读取(值a)其中
readsPrec_m = readsMatrix m
readsMatrix ::(读取a)=> ReadS(Value a)
readsMatrix(' - ':s)= [(Nul,rest)| ('',rest)< - 读取s]
readsMatrix s = [(Val x,rest)| (x,'':rest)< - 读取s]
执行此测试后: p>
读取 - 8 - - 3:: Value Int
我得到错误 *** Exception:Prelude.read:no parse
我在这里做错了什么?
更新
readsMatrix(' - ':s)= [(Nul,dropWhile isSpace s)]
readsMatrix s = [(Val x,dropWhile isSpace rest) (x,rest)< - reads s]
改正值的读取a
首先,不要打扰删除空格,这一切都可以通过 reads
处理:
readsMatrix ::(阅读a)=> ReadS(Value a)
readsMatrix(' - ':s)= [(Nul,dropWhile(=='')s)]
readsMatrix s = [(Val x,rest)| (x,rest)< - 读取s]
*主要>阅读4:: Value Int
Value4
* Main> read - :: Value Int
Nothing 0
正确读取[Value a]
但是你想读取由空格分隔的列表,因为这是非标准行为,所以你需要编写一个自定义的 readList: ::: ReadS [Value a]
instance读取a =>读取(值a)其中
$因此,现在
readsPrec _ m = readsMatrix m
readList s = [(map read.words $ s,)]
* Main> pre
阅读 - 4 2 - 5:: [Value Int]
[Nothing 0,Value4,Value2,Nothing 0,Value5]
但不幸的是,
* Main>阅读 - 4 2 \ n - 5 4:: [Value Int]
pre>
[Nothing 0,Value4,Value2,Nothing 0,Value5,Value4]
甚至更糟,
*主要>阅读 - 4 2 \ n - 5 4:: [[Value Int]]
***例外:Prelude.read:不分析
阅读一个矩阵
没有简单的方法可以看到,因为没有
readListOfLists
在Read
类中,所以为什么不做一个独立的函数matrix :: Read a =>字符串 - > [[Value a]]
matrix = map read.lines
这样
* Main>矩阵3 4 - \\ n3 - 6 \ n4 5 - :: [[Value Int]]
[[Value3,Value4,Nothing 0],[Value3,Nothing 0,Value6],[Value4, Value5,Nothing 0]]
显示不是我想要的选项
我认为您的
显示实例
Value
有点误导(Nul
没有零,Val
没有被写入值
)。要么写
data数值a = Nul | Val a派生显示
以便它看起来像它或将其定义为匹配
Read
instanceinstance显示a =>显示(值a)其中
显示Nul = -
显示(Val a)=显示
I want to implement an instance of read that enables me to read a string (ex: "- - 8 - 3 -") and construct a list containing those values.
data Value a = Nul | Val a showsValue :: (Show a) => Value a -> ShowS showsValue (Val x) = ("Value" ++) . shows x showsValue (Nul) = ("Nothing 0" ++) instance Show a => Show (Value a) where showsPrec _ x = showsValue x instance Read a => Read (Value a) where readsPrec _ m = readsMatrix m readsMatrix :: (Read a) => ReadS (Value a) readsMatrix ('-':s) = [(Nul, rest) | (' ',rest) <- reads s] readsMatrix s = [(Val x,rest)| (x,' ':rest) <- reads s]
After performing this test:
read "- 8 - - 3" :: Value Int
I get the error
*** Exception: Prelude.read: no parse
What am I doing wrong here?
update
readsMatrix ('-':s) = [(Nul, dropWhile isSpace s)] readsMatrix s = [(Val x, dropWhile isSpace rest) | (x,rest) <- reads s]
解决方案Correcting read for Value a
First, don't bother removing spaces, that's all handled fine by
reads
:readsMatrix :: (Read a) => ReadS (Value a) readsMatrix ('-':s) = [(Nul, dropWhile (==' ') s)] readsMatrix s = [(Val x,rest)| (x,rest) <- reads s]
Your read instance is now fine for single Values:
*Main> read "4" :: Value Int Value4 *Main> read "-" :: Value Int Nothing 0
Correcting read for [Value a]
But you want to read lists as separated by spaces, so since that's non-standard behaviour, you'll need to write a custom
readList :: :: ReadS [Value a]
instance Read a => Read (Value a) where readsPrec _ m = readsMatrix m readList s = [(map read.words $ s,"")]
So now
*Main> read "- 4 2 - 5" :: [Value Int] [Nothing 0,Value4,Value2,Nothing 0,Value5]
but unfortunately,
*Main> read "- 4 2 \n- 5 4" :: [Value Int] [Nothing 0,Value4,Value2,Nothing 0,Value5,Value4]
and even worse,
*Main> read "- 4 2 \n- 5 4" :: [[Value Int]] *** Exception: Prelude.read: no parse
Reading a matrix
There's no straightforward way round this that I can see, because there's no
readListOfLists
in theRead
class, so why not make a standalone functionmatrix :: Read a => String -> [[Value a]] matrix = map read.lines
so that
*Main> matrix "3 4 -\n3 - 6\n4 5 -" :: [[Value Int]] [[Value3,Value4,Nothing 0],[Value3,Nothing 0,Value6],[Value4,Value5,Nothing 0]]
Show isn't what I would choose
I think your
Show
instance forValue
is a little misleading (Nul
doesn't have a zero on it,Val
isn't writtenValue
). Either writedata Value a = Nul | Val a deriving Show
so that it looks as it is or define it to match the
Read
instanceinstance Show a => Show (Value a) where show Nul = "-" show (Val a) = show a
这篇关于读实例导致解析错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!