绳子到整数解析,并在Haskell中进行例外处理
尝试制作类型nat
哪个返回[(int,string)];将零作为字符串
和类型 int 处理,它也可以处理负整数。
import Data.Char ( isDigit )
type Parser tok a = [tok] -> [(a, [tok])]
return :: a -> Parser tok a
return v = \ts -> [(v, ts)]
failure :: Parser tok a
failure = \_ -> []
item :: Parser tok tok
item [] = []
item (t:ts) = [(t, ts)]
sat :: (tok -> Bool) -> Parser tok tok
sat test = item >>= \t ->
if test t then return t
else failure
(<|>) :: Parser tok a -> Parser tok a -> Parser tok a
p1 <|> p2 = \ts -> case p1 ts of
[] -> p2 ts
rs1 -> rs1
many1 :: Parser tok a -> Parser tok [a]
many p = many1 p <|> return []
many1 p = p >>= \v ->
many p >>= \vs ->
return (v:vs)
digit = sat isDigit
首先,我制作nat并使用〜然后使用〜然后〜else〜其他例外。
nat :: Parser Char Int
nat = many1 digit >>= \s ->
if (s == "0") then failure
else return (read s)
它是能够处理一个零。
nat "0"
> []
nat "0def"
> []
但是当连续数字从0开始时无法处理。
nat "012def"
> [(12, "def")] -- probably my code only handle 1 Zero
-- expect return []
nat "000def"
> [(0, "def")] -- but i really don't know why this output is coming
-- expect return []
我试图将有关NAT的问题放在一边,然后先制作INT。
首先,我尝试使用NAT定义INT。
int :: Parser Char Int
int = nat >>= \s ->
if (s < 0) then return (-s)
else return s
而且我意识到我无法使编译器认识到S是负面的。
因此,我试图使其像Nat一样。我想添加char' - '?
int :: Parser Char Int
int = many1 digit >>= \s ->
if (s == "-") then return (read s) ++ "-"
else return (read s)
我有两个问题
为什么nat只处理1个零?我以为Muran1是递归解析字符串。
如何在int中添加“ - ”?它与诸如合成功能之类的细胞有关吗?
我在使用Haskell方面很虚弱。我缺少什么吗?
Trying to make type nat
which return [ (int, string) ]; handle zero as string
and type int
which can handle negative integer also.
import Data.Char ( isDigit )
type Parser tok a = [tok] -> [(a, [tok])]
return :: a -> Parser tok a
return v = \ts -> [(v, ts)]
failure :: Parser tok a
failure = \_ -> []
item :: Parser tok tok
item [] = []
item (t:ts) = [(t, ts)]
sat :: (tok -> Bool) -> Parser tok tok
sat test = item >>= \t ->
if test t then return t
else failure
(<|>) :: Parser tok a -> Parser tok a -> Parser tok a
p1 <|> p2 = \ts -> case p1 ts of
[] -> p2 ts
rs1 -> rs1
many1 :: Parser tok a -> Parser tok [a]
many p = many1 p <|> return []
many1 p = p >>= \v ->
many p >>= \vs ->
return (v:vs)
digit = sat isDigit
first I make nat and use if ~ then ~ else make exception of 0.
nat :: Parser Char Int
nat = many1 digit >>= \s ->
if (s == "0") then failure
else return (read s)
It was able to handle one zero.
nat "0"
> []
nat "0def"
> []
but can't handle when consecutive numbers starting with 0 come to input.
nat "012def"
> [(12, "def")] -- probably my code only handle 1 Zero
-- expect return []
nat "000def"
> [(0, "def")] -- but i really don't know why this output is coming
-- expect return []
I tried to put aside the problem about nat and make an int first.
first I tried to use nat to define int.
int :: Parser Char Int
int = nat >>= \s ->
if (s < 0) then return (-s)
else return s
And I realize that i can't make to compiler recognize that s is negative.
so i tried to make it simillar as nat. which I want to add char '-'?
int :: Parser Char Int
int = many1 digit >>= \s ->
if (s == "-") then return (read s) ++ "-"
else return (read s)
I have two question
Why nat only handle 1 zero? I thought many1 is recursive parsing string step-by-step.
How can I add "-" in int? does it related with thins like synthetic function?
I am weak at using Haskell. is there something i'm missing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不要恐慌。这不是那么困难。
您是正确的
MOUS1 DIGIT
将在可能的较长链上应用解析器数字。这意味着,当您解析012DEF
解析部分为“ 012”,其余部分为“ DEF”。但是您缺少错误的位置。在以下内容中,
mus1 digit
完成它通过bind(&gt;&gt; =
)向您的函数提供了“ 012”,并且是过程。但是“ 012”不是“ 0”。因此,应用了else
零件:return(读取“ 012”)
。上下文“ def”
未修改。因此,这将导致答案[12,“ def”]。如您所见,问题不是绑定的第一部分,而是第二部分。既然您知道您只会获得数字(因为Moan1 Digit
只能分析数字),我建议您使用更优雅的(monadic)解决方案更改活页夹,但这可能是可以读取的。并明确针对新的Haskeller。
你不能。您想读取无法将其翻译成数字的
char
。因此,您无法将其视为数字。这是一个简单的解析问题。您必须单独处理' - ' - ' - '
。您可以在两个解析器之间使用选择。第一个解析char
' - '
,其次是自然。第二次解析自然。然后将结果转换为int
。注意不要忘记0
。它可以在第一,第二或两者中进行处理。这意味着您不能在两者中使用nat
...或者您必须制作第三个解析器,仅解析0
。因此请记住,该顺序很重要。我很确定,考虑到以前的工作,可以写这篇文章。您已经拥有数字和选择组合。
char
解析器很明显。您只需要考虑一下即可。希望这会有所帮助。
Don't panic. It is not so difficult.
You are right
many1 digit
will apply the parser digit on the longer chain possible. This means that when you are parsing012def
the parsed part is "012" and the remaining is "def". But you are missing where the error is. It is in the followingOnce,
many1 digit
finish it provides "012" to your function via the bind (>>=
) and it is process. But "012" is not "0". So theelse
part is applied :return (read "012")
. The context"def"
is not modified. So this results to the answer [12,"def"]. As you can see the problem is not the first part of the bind, but the second one. Since you know that you will only get digit (becausemany1 digit
can only parse digit), I suggest that you change your binder withMore elegant (monadic) solution are possibles, but this one is probably quite readable and explicit for new haskeller.
You can't. You want to read a
Char
that cannot be translate as a digit. So you can't read it as digit. This is a simple parsing problem. You have to deal with the'-'
separately. You can use a choice between two parsers. The first parses theChar
'-'
followed by a natural. The second parses only natural. Then translate the result in anInt
. Take care to not forget the0
. It can be handle in the first, the second or both. This means that you can't usenat
in both... or you will have to make a third parser that only parse0
. So remember that the order is important.I am pretty sure that can be write this considering the previous work. You already have the digit and the choice combinator. The
char
parser is pretty obvious. You just have to think about it.Hope this will help.