これはそれを行います:
import Control.Monad
subseq a b = elem a . filterM (\x-> [True,False]) $ b
(SO / sacundimに感謝します!)。
jacobm's answerからアドバイスを受けると、
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