haskell - haskell return [] 用于来自解析器函数的数据
问题描述
在下面的代码中,我应该在运行 parse noun 后得到 []:
parse noun "something" = []
不幸的是,我无法更改函数的签名,所以也许不是一个选项。运行parse noun "something"时如何从名词函数返回 [] ?(我不想返回“c”变量)非常感谢您的帮助。
import Parsing
data Tree = Branch Sort [Tree]
| Leaf Sort String deriving (Eq, Show)
nouns :: [String]
nouns = ["flight", "breeze", "trip", "morning"]
oneOf :: [String] -> Parser String
oneOf l = do
cs <- token identifier
guard (elem cs l)
return cs
noun :: Parser Tree
noun = do
cs <- token identifier
let a = Leaf Noun cs
let b = parse (oneOf nouns) cs
let c = Leaf Noun []
if null b then return c else return a
-- Parsing.hs
-- Functional parsing library from chapter 13 of Programming in Haskell,
-- Graham Hutton, Cambridge University Press, 2016.
module Parsing (module Parsing, module Control.Applicative) where
import Control.Applicative
import Data.Char
-- Basic definitions
newtype Parser a = P (String -> [(a,String)])
parse :: Parser a -> String -> [(a,String)]
parse (P p) inp = p inp
item :: Parser Char
item = P (\inp -> case inp of
[] -> []
(x:xs) -> [(x,xs)])
-- Sequencing parsers
instance Functor Parser where
-- fmap :: (a -> b) -> Parser a -> Parser b
fmap g p = P (\inp -> case parse p inp of
[] -> []
[(v,out)] -> [(g v, out)])
instance Applicative Parser where
-- pure :: a -> Parser a
pure v = P (\inp -> [(v,inp)])
-- <*> :: Parser (a -> b) -> Parser a -> Parser b
pg <*> px = P (\inp -> case parse pg inp of
[] -> []
[(g,out)] -> parse (fmap g px) out)
instance Monad Parser where
-- (>>=) :: Parser a -> (a -> Parser b) -> Parser b
p >>= f = P (\inp -> case parse p inp of
[] -> []
[(v,out)] -> parse (f v) out)
-- Making choices
instance Alternative Parser where
-- empty :: Parser a
empty = P (\inp -> [])
-- (<|>) :: Parser a -> Parser a -> Parser a
p <|> q = P (\inp -> case parse p inp of
[] -> parse q inp
[(v,out)] -> [(v,out)])
-- Derived primitives
sat :: (Char -> Bool) -> Parser Char
sat p = do x <- item
if p x then return x else empty
digit :: Parser Char
digit = sat isDigit
lower :: Parser Char
lower = sat isLower
upper :: Parser Char
upper = sat isUpper
letter :: Parser Char
letter = sat isAlpha
alphanum :: Parser Char
alphanum = sat isAlphaNum
char :: Char -> Parser Char
char x = sat (== x)
string :: String -> Parser String
string [] = return []
string (x:xs) = do char x
string xs
return (x:xs)
ident :: Parser String
ident = do x <- lower
xs <- many alphanum
return (x:xs)
nat :: Parser Int
nat = do xs <- some digit
return (read xs)
int :: Parser Int
int = do char '-'
n <- nat
return (-n)
<|> nat
-- Handling spacing
space :: Parser ()
space = do many (sat isSpace)
return ()
token :: Parser a -> Parser a
token p = do space
v <- p
space
return v
identifier :: Parser String
identifier = token ident
natural :: Parser Int
natural = token nat
integer :: Parser Int
integer = token int
symbol :: String -> Parser String
symbol xs = token (string xs)
解决方案
感谢chi找到了解决方案:
noun :: Parser Tree
noun = do
cs <- token identifier
guard (elem cs nouns)
let a = Leaf Noun cs
return a
推荐阅读
- python - 缺少 Python 类属性
- java - Open Liberty 19.0.0.3 中的消息驱动 Bean 在访问 ActiveMQ 时未激活
- c++ - While 循环在一个函数调用中执行两次
- swift - 如何仅在 SceneKit 球体的一部分上应用菲涅尔效果?
- neo4j - 找到具有关系条件的最短路径
- asp.net-mvc - url 中存在尾随句点时出现 404 错误
- angular - 当默认加载器已经变得更安全时,为什么 PyYAML 5.1 会引发 YAMLLoadWarning?
- ios - 在按钮中的文本两侧添加填充
- forms - Concrete5 商店不允许我输入信用卡详细信息
- github - 分叉和编辑的 GitHub 网站上的页面导航按钮不再起作用