这样做:
import Control.Monad
subseq a b = elem a . filterM (\x-> [True,False]) $ b
(为此感谢 SO / sacundim!)。
从 jacobm 的回答中得到建议,你会得到
subseq [] ys = True
subseq xs [] = False
subseq (x:xs) (y:ys) = x == y && (....)
|| x /= y && subseq (....) (....)
用警卫写得更好,
subseq (x:xs) (y:ys)
| x == y = (....)
| otherwise = subseq (....) (....)
第一个代码最好被视为规范,而不是代码,它非常低效。为了改进它,我们可以尝试融合 elem
和filterM
- 这可能已经实现为
filterM p xs = liftM concat $ sequence [ do {t<-p x; return [x|t]} | x<-xs]
以便
elem xs $ filterM (\x-> [True,False]) ys ==
elem xs $ map concat $ sequence [ [[y|t] | t<-[True,False]] | y<-ys] ==
elem xs $ map concat $ sequence [ [[y],[]] | y<-ys] ==
not.null $ filter (match [[x]|x<-xs]) $ sequence [ [[y],[]] | y<-ys]
where
match [] _ = True
match _ [] = False
match ([x]:t) ([y]:s) | x==y = match t s
match q (_:s) = match q s ==
not.null $ [()|r<-sequence [ [[y],[]] | y<-ys], match [[x]|x<-xs] r] ==
match2 xs ys
where
match2 [] _ = True
match2 _ [] = False
match2 (x:t) (y:s) | x==y = match2 t s
match2 q (_:s) = match2 q s