2014-10-05 81 views
1

我想繼續應用解析器到一個字符串,並添加它的輸出,直到我到達字符串的末尾。不幸的是,當我解析字符串的結尾時,它失敗了,所以我得到一個空列表。我希望能夠檢查解析是否失敗,然後在解析失敗之前從所有解析中獲得輸出。我正試圖將這個字符串解析成一個浮點列表。我怎樣才能阻止這種情況的發生(即獲得一個空的列表而不是我的浮動列表)。如何檢查解析是否失敗?

我寫這種類型的解析器:newtype Parser a = MkP (String -> [(String,a)]) 及其單子實例是這樣的:

-- (>>=) :: 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 => []

整個代碼是在這裏:

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
helper y = do 
    a <- randomthing 
    helper (y ++ [a]) 

什麼是當randomthing失敗

a從0到randomthing產生一個空列表。

如果你看>>=的定義,g適用於firstout對於applyParser f inp中的每個結果。因此,如果applyParser f inp產生零結果,則應用g零次。

在幫手f的定義是randomthingg\a -> helper (y ++ [a])。所以,如果g從未應用(這是不是當randomthing produces an empty list for the given input)a不具有價值,因爲只有a裏面g存在。

我希望能夠檢查一個解析失敗

你不能使用monadic接口來做,而必須自己使用applyParser,然後檢查它是否返回空列表