我想继续将解析器应用于字符串,并添加其输出,直到我到达字符串的末尾。不幸的是,当我解析字符串的结尾时,它失败了所以我得到一个空列表。我希望能够检查解析是否失败,然后在失败的解析之前获取所有解析的输出。我试图将此字符串解析为浮点列表。如何阻止这种情况发生(即获取一个空列表而不是我的浮动列表)。
我编写了一个这种类型的解析器:newtype Parser a = MkP (String -> [(String,a)])
它的monad实例是这样的:
-- (>>=) :: m a -> (a -> m b) -> m b
instance Monad Parser where
return x = MkP f
where
f inp = [(inp,x)]
f >>= g = MkP s
where
s inp = [(rest,out) | (firstremain,firstout) <- applyParser f inp, (rest,out) <- applyParser (g firstout) firstremain]
失败的解析由空列表[]表示。我有这些主要的解析器:
item :: Parser Char
item = MkP f
where
f [] = []
f (x:xs) = [(xs,x)]
zero :: Parser Char
zero = MkP f
where
f _ = []
我正在尝试解析此字符串:
unparsedboeyield = "0.63 0.81 1.01 1.20 1.38 1.54 1.68 1.79 1.89 1.97 2.05 2.11 2.17 2.23 2.28 2.33 2.37 2.42 2.45 2.49 2.53 2.56 2.59 2.62 2.64 2.67 2.69 2.71 2.73 2.75 2.77 2.79 2.80 2.82 2.83 2.84 2.85 2.87 2.87 2.88 2.89 2.90 2.90 2.91 2.91 2.92 2.92 2.92 2.93 2.93"
使用此解析器:
numberParser :: Parser Float
numberParser = do
a <- item
b <- item
c <- item
d <- item
let number = read [a,b,c,d] :: Float in return number
yieldParser :: Parser [Float]
yieldParser = do
x <- numberParser
helper [x] where
helper y = do
a <- randomthing
helper (y ++ [a])
randomthing = do
item
item
item
item
numberParser
我不明白在helper
时发生了什么,什么是a
当randomthing失败时(它不能是[]那么它会引发类型错误,因为它不是浮动)。当我尝试解析字符串时会发生这种情况:
applyParser yieldParser boeunparsedyield =&gt; []
整个代码在这里:
import Control.Monad
import Data.Char
interpolate :: (Ord a, Fractional a) => ((a,a),(a,a)) -> a -> a
interpolate ((x1,y1),(x2,y2)) x = if (x > x2) || (x < x1) then error "value out of range" else y1 + difference * gradient
where
gradient = (y1 -y2)/(x1 - x2)
difference = x - x1
pvt :: Fractional a => a -> Int -> a
pvt x t = x / (m + spotrate t)^t where m = 1 :: Fractional a => a
unparsedboeyield :: String
unparsedboeyield = "0.63 0.81 1.01 1.20 1.38 1.54 1.68 1.79 1.89 1.97 2.05 2.11 2.17 2.23 2.28 2.33 2.37 2.42 2.45 2.49 2.53 2.56 2.59 2.62 2.64 2.67 2.69 2.71 2.73 2.75 2.77 2.79 2.80 2.82 2.83 2.84 2.85 2.87 2.87 2.88 2.89 2.90 2.90 2.91 2.91 2.92 2.92 2.92 2.93 2.93"
newtype Parser a = MkP (String -> [(String,a)])
applyParser :: Parser a -> String -> [(String,a)]
applyParser (MkP x) y = x y
-- (>>=) :: m a -> (a -> m b) -> m b
instance Monad Parser where
return x = MkP f
where
f inp = [(inp,x)]
f >>= g = MkP s
where
s inp = [(rest,out) | (firstremain,firstout) <- applyParser f inp, (rest,out) <- applyParser (g firstout) firstremain]
item :: Parser Char
item = MkP f
where
f [] = []
f (x:xs) = [(xs,x)]
zero :: Parser Char
zero = MkP f
where
f _ = []
sat :: (Char -> Bool) -> Parser Char
sat predicate =
item >>= \x ->
if predicate x then return x else zero
doParser :: Parser a -> Int -> Parser ()
doParser x count = helper count
where
helper count = do
if count > 0 then do
x
helper (count - 1)
else return ()
numberParser :: Parser Float
numberParser = do
a <- item
b <- item
c <- item
d <- item
let number = read [a,b,c,d] :: Float in return number
yieldParser :: Parser [Float]
yieldParser = do
x <- numberParser
helper [x] where
helper y = do
a <- randomthing
helper (y ++ [a])
randomthing = do
item
item
item
item
numberParser
spotrate :: Fractional a => Int -> a
spotrate = \t -> if (t == 1) then 5 else 2
untilParser :: (Char -> Bool) -> Parser [Char]
untilParser p = helper []
where
helper x = do
y <- item
if p y then helper (x ++ [y]) else return x
答案 0 :(得分:0)
helper y = do
a <- randomthing
helper (y ++ [a])
<什么是随机事件失败
a
在randomthing
生成空列表时, >>=
永远不会获得值。
如果您查看g
的定义,firstout
会针对applyParser f inp
中的每个结果应用applyParser f inp
。因此,如果g
结果为零,则f
将应用零次。
助手randomthing
的定义是g
,\a -> helper (y ++ [a])
是g
。因此,如果永远不会应用randomthing produces an empty list for the given input)
(a
不是a
,g
没有值,因为applyParser
只存在于{{1}}内。< / p>
我希望能够检查解析是否失败
使用monadic界面无法做到这一点。相反,您必须自己使用{{1}},然后检查它是否返回空列表。