試圖使nat回傳的型別[ (int, string) ]; handle zero as string
和int可以處理的型別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
首先我制作 nat 并使用 if ~ then ~ else 使 0 例外。
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 一樣。我想添加字符'-'?
int :: Parser Char Int
int = many1 digit >>= \s ->
if (s == "-") then return (read s) "-"
else return (read s)
我有兩個問題
為什么 nat 只處理 1 個零?我認為 many1 是逐步遞回決議字串。
如何在 int 中添加“-”?它與諸如合成功能之類的東西有關嗎?
我不擅長使用 Haskell。有什么我想念的嗎?
uj5u.com熱心網友回復:
不要恐慌。這并不難。
- 為什么 nat 只處理 1 個零?我認為 many1 是逐步遞回決議字串。
您是對many1 digit的,會將決議器數字應用到可能的更長鏈上。這意味著當您決議時012def,決議的部分是“012”,其余的是“def”。但是您錯過了錯誤所在。它在以下
\s -> if (s == "0") then failure
else return (read s)
一次,many1 digit完成它通過系結()為您的函式提供“012” >>=,它就是程序。但是“012”不是“0”。所以這else部分被應用了:return (read "012")。背景關系"def"沒有被修改。所以這導致答案[12,“def”]。如您所見,問題不是系結的第一部分,而是第二部分。既然你知道你只會得到數字(因為many1 digit只能決議數字),我建議你改變你的活頁夾
let n = read s
in if n == 0 then failure
else n
更優雅的(單子)解決方案是可能的,但對于新的 haskeller 來說,這個解決方案可能非常易讀和明確。
- 如何在 int 中添加“-”?它與諸如合成功能之類的東西有關嗎?
你不能。您想閱讀Char無法翻譯為數字的 a。所以你不能把它讀成數字。這是一個簡單的決議問題。你必須分別處理'-'。您可以在兩個決議器之間進行選擇。第一個決議Char '-'后跟一個自然的。第二個決議只是自然的。然后將結果翻譯成Int. 注意不要忘記0. 它可以在第一個,第二個或兩者中處理。這意味著您不能nat在兩者中都使用...或者您將不得不制作第三個僅決議 parse 的決議器0。所以請記住,順序很重要。
考慮到以前的作業,我很確定可以寫這個。您已經有了數字和選擇組合器。char決議器非常明顯。你只需要考慮一下。
希望這會有所幫助。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/487878.html
標籤:哈斯克尔
