读实例导致解析错误 [英] read instance causes parse error

查看:86
本文介绍了读实例导致解析错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现一个读取实例,使我能够读取一个字符串(例如: - - 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] 
[Nothing 0,Value4,Value2,Nothing 0,Value5,Value4]
pre>

甚至更糟,

  *主要>阅读 -  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 instance

  instance显示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 the Read class, so why not make a standalone function

matrix :: 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 for Value is a little misleading (Nul doesn't have a zero on it, Val isn't written Value). Either write

data Value a = Nul | Val a  deriving Show

so that it looks as it is or define it to match the Read instance

instance Show a => Show (Value a) where
  show Nul = "-"
  show (Val a) = show a

这篇关于读实例导致解析错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆