这是代码:
import Data.List
data RE sym
= Never -- match no strings
| Empty -- match empty string
| Symbol sym -- match singleton string
| RE sym :+ RE sym -- choice
| RE sym :* RE sym -- concatenation
| Repeat (RE sym) -- repeat zero or more times
| Plus (RE sym) -- repeat one or more times
deriving (Show, Eq)
infixr 6 :+, .+.
infixr 7 :*, .*.
data ABC = A | B | C deriving (Show, Eq, Ord)
编写一个matchEmpty函数,该函数对于与空字符串匹配的正则表达式返回true。
matchEmpty :: RE sym -> Bool
matchEmpty = ???
这就是我写的:
matchEmpty (Empty :+ _) = True
matchEmpty Empty = True
matchEmpty Never = False
matchEmpty (_) = False
matchEmpty(Repeat(_)) = True
但是在某些情况下我仍然出错:
Testing matchEmpty
INCORRECT: A*
wanted: True
got: False
INCORRECT: (A|e)+
wanted: True
got: False
INCORRECT: (AB)*
wanted: True
got: False
我为此迷茫,请帮助我做到这一点,我是Haskell的初学者,请尝试自己学习。 是否需要递归或其他方法来解决此问题?
答案 0 :(得分:1)
您似乎遇到的问题是
Repeat (Symbol A)
被错误地标记为false。
这是因为模式是从上到下匹配的,所以matchEmpty (_) = False
会捕获它而不是matchEmpty(Repeat(_)) = True
Plus (x)
总是错误地标记为false。
当x
与空字符串匹配时,这应该为真(是的,这将是递归检查)。
x :- y
为x
时, Empty
被正确地标记为true,但是在以下情况下错误地失败了:
Symbol A :+ Empty
-另一面是空的
(Repeat _) :+ (Empty :+ Empty)
-Empty
本身都不是一方,但仍匹配空字符串(这也将是递归检查)
x :* y
始终被错误地标记为false。当双方双方都可以匹配空字符串(也是递归的)时,这应该是正确的。
您现在可以通过这些观察再次尝试一下。
对于破坏者,这是我的建议:
matchEmpty Empty = True
matchEmpty (Repeat _) = True
matchEmpty (Plus x) = matchEmpty x
matchEmpty (x :+ y) = matchEmpty x || matchEmpty y
matchEmpty (x :* y) = matchEmpty x && matchEmpty y
matchEmpty _ = False