2013-05-10 2 views
3

컨텍스트에 넣으려는 경우, "패턴 필터링"을 수행하는 목록 이해 (do3와 bind)에 대한 목록 이해 (do3와 bind)를 변환 한 다음 예외를 만났습니다 . 나는 이러한 정의 (BF가 breadthFirst에 대한 보유)로 시작바인딩에 대해서는 제외하지만 do not에 대해서는

,

상황, 데이터 및 도우미

data Tree a = Leaf | Node a (Tree a) (Tree a) deriving Show 
let test = Node 1 (Node 2 (Node 4 Leaf Leaf) Leaf) (Node 3 Leaf (Node 5 Leaf Leaf)) 
let nextChild = concatMap (\x -> case x of; Leaf -> []; Node n l r -> [l,r]) 

기능은

let bfLc xs | null xs = [] | otherwise = [ n | Node n _ _ <- xs] ++ (bfLc $ nextChild xs) 
let bfDo xs | null xs = [] | otherwise = (do {Node n _ _ <- xs; return n}) ++ (bfDo $ nextChild xs) 
let bfBind xs | null xs = [] | otherwise = (xs >>= \(Node n _ _) -> [n]) ++ (bfBind $ nextChild xs) 

테스트 그리고 나는이 작업을 수행 평가,

,
bfLc [test] 
[1,2,3,4,5] 

bfDo [test] 
[1,2,3,4,5] 

bfBind [test] 
[1,2,3,4*** Exception: <interactive>:103:53-72: Non-exhaustive patterns in lambda 

하지만 there

할 구문에서 배운는 모나드 연산의 체인에 대한 간단한 속기를 제공합니다. DO의 필수 번역은 다음과 같은 두 가지 규칙 캡처 : 그들은 동일에도 불구하고

do e1 ; e2  = e1 >> e2 
    do p <- e1; e2 = e1 >>= \p -> e2 

bfBindbfDo에 반대하지 않는다?
개인적으로 모두 실패했을 것으로 예상되었지만 목록 이해력 또는 Do 표기법이 성공하는 이유를 모르겠습니다. (그렇다면이 하위 질문에도 답변 할 수 있다면)

고마워.

답변

6

이것은 실패한 패턴이 do 표기법과 일치하므로 Monad 클래스의 fail 함수를 호출하기 때문에 발생합니다.

특히

,이 표현식이 실제로 desugared 도착하는 방법입니다

여기 p
do {p <- e; stmts} = let ok p = do {stmts} 
          ok _ = fail "..." 
    in e >>= ok 

은 예로부터 Node n _ _처럼, 어떤 패턴이다.

는 (하스켈 보고서 do expressions 섹션을 살펴보십시오.) 다음과 같이

[]Monad 인스턴스 fail을 정의

fail _ = [] 
+0

은'Maybe'에서 fail''의 정의 인스턴스가 가장 강력한 IMO입니다. – amindfv

관련 문제