이것은 구문 분석 문제와 매우 유사합니다, 그래서 파서 모나드에서 힌트를 보자 :
match
는
- 이 일치가 실패하면 해석의 가능성 연속성을 모든 목록을 반환해야 빈 목록을 반환해야
- 과제의 현재 세트는
우리가 향하고 곳의 스와하게 볼 수있는 계산을 통해 수행에이 상태가 될 것입니다 우리는이 마법의 모나드를 가지고 있습니다. 그것은이 모나드는리스트 모나드를 통해 국가 모나드입니다 밝혀
matchAbba = do
var 'a'
var 'b'
var 'b'
var 'a'
return() -- or whatever you want to return
test = runMatch matchAbba "redbluebluered"
: 같은 문자열에 대해 "아바"을 일치하려고하면 찾을 것입니다. List 모나드는 backtracking을 제공하고 State 모나드는 현재 할당과 입력을 전달합니다.
import Data.List
import Control.Monad
import Control.Monad.State
import Control.Monad.Trans
import Data.Maybe
import qualified Data.Map as M
import Data.Monoid
type Assigns = M.Map Char String
splits xs = tail $ zip (inits xs) (tails xs)
var p = do
(assigns,input) <- get
guard $ (not . null) input
case M.lookup p assigns of
Nothing -> do (a,b) <- lift $ splits input
let assigns' = M.insert p a assigns
put (assigns', b)
return a
Just t -> do guard $ isPrefixOf t input
let inp' = drop (length t) input
put (assigns, inp')
return t
matchAbba :: StateT (Assigns, String) [] Assigns
matchAbba = do
var 'a'
var 'b'
var 'b'
var 'a'
(assigns,_) <- get
return assigns
test1 = evalStateT matchAbba (M.empty, "xyyx")
test2 = evalStateT matchAbba (M.empty, "xyy")
test3 = evalStateT matchAbba (M.empty, "redbluebluered")
matches :: String -> String -> [Assigns]
matches pattern input = evalStateT monad (M.empty,input)
where monad :: StateT (Assigns, String) [] Assigns
monad = do sequence $ map var pattern
(assigns,_) <- get
return assigns
시도, 예를 들면 :
matches "ab" "xyz"
-- [fromList [('a',"x"),('b',"y")],fromList [('a',"x"),('b',"yz")],fromList [('a',"xy"),('b',"z")]]
지적하는 또 다른 것은 모나드 값을 "아바"와 같은 문자열을 변환하는 코드가 do var'a'; var'b'; var 'b'; var 'a'
단순히입니다 여기에
코드입니다 :
sequence $ map var "abba"
업데이트 : @Sassa NF가 지적한대로
matchEnd :: StateT (Assigns,String) []()
matchEnd = do
(assigns,input) <- get
guard $ null input
을 다음 모나드에 삽입 : 정의 할 수 있습니다 넣어 여기
monad = do sequence $ map var pattern
matchEnd
(assigns,_) <- get
return assigns
일반적인 파서 문제와 마찬가지로 여기서 입력을 완전히 구문 분석해야합니다. 마지막 두 줄 수정 :'(assigns, r) <- get; 가드 $ r == []; return은 ' –
'시퀀스를 할당합니다. map f는'mapM f'입니다. – Cactus