2013-11-20 4 views
1

에서 (모나드) 계산의 결과를 폐기하는 방법, 내가 쓸 수 있습니다 : 제대로 하스켈에서 F 번호

token: Parser a -> Parser a 
token p = do space 
      v <- p 
      space 
      return v 

이 F 번호에서, 내가 여기까지 온

: 즉

let token = compose { 
     let! _ = space 
     let! v = parser 
     let! _ = space 
     return v 
    } 

을, 이 사용하지 않는 let! _ = 바인딩을 도입하여 "space"파서 (모나드)의 구문 분석 값을 무시하고 필요는 없다.

F #에서 이러한 쓸모없는 바인딩을 방지하려면 어떻게해야합니까? 내가 사용하는 시도!하지만 난 오류가 (내 >>= 기능 형 유닛을 가지고 있지만하지 않기 때문에 'A) :

type ParserComposer() = 
    member x.Bind(p, f) = p >>= f 
    member x.Return(y) = ret y 
    member x.Zero() = failure 

내가해야합니까 :

여기
let (>>=) (p: Parser<'a>) (f: 'a -> Parser<'b>) : Parser<'b> 

내 빌더 정의입니다 >> 함수를 정의 하시겠습니까? 빌더에 결합()을 추가 하시겠습니까? 어떤 아이디어가이 일을 올바르게하는 방법? 코드 예제? space의 반환 유형을 가정

+0

당신은 이미 표준 연산자이므로 다른 이름으로'>>'를 정의 할 수 있습니다. 예 : https://github.com/fsharp/fsharpx/blob/9ad7ff3024b1cc90fd252520272421920c1f4017/src/FSharpx.Core/ComputationExpressions/Monad.fs#L779 –

+0

좋아요. 다른 이름으로 >>를 정의한 경우 어떻게해야합니까? ? – badbadboy

+0

하스켈에서 사용 하듯이 사용합니다. 아니면'let! _ = ...' –

답변

5

Parser<unit>입니다 (그것이 어떤 결과를 반환하는 파서를 나타내지 않는 경우 의미가 것이다) 당신은 쓸 수 있습니다 :

let token = compose { 
    do! space 
    let! v = parser 
    do! space 
    return v 
} 

이것은 당신이 쓴 것에 대해 단지 문법 설탕입니다 - 따라서 do! elet! _ = e으로 번역되며, parser.Bind(e, fun _ -> ...)으로 변환됩니다. Combine 및 몇 가지 (가능하면) 유용한 것을 정의하는 Additive parsers on Try Joinads의 샘플이 있지만 do! 키워드는 Bind 만 필요합니다.

+2

이 경우 공백은 파서 이므로 "할!"을 사용할 수 있습니다. 그러나 그것이 다른 것의 파서 인 경우에는 어떨까요? 많은 경우 유용한 정보를 반환하지만 필요하지 않습니다. 하스켈에서는이 경우 단순히 바인딩하지 않습니다. F #에서 처리하는 가장 좋은 방법은 무엇입니까? 그러면 Combine은 내가 사용해야하는 것입니까? – badbadboy

+0

@badbadboy :이 경우에도'do!'를'Bind' 문서로 사용할 수 있습니다. 계산식에서'Called for let! 하고! 계산식에서 ' – Ankur

+0

그렇습니다. 그렇기 때문에 컴파일 오류가 발생합니다! 호출 서로 다른 유형 ('a)을 기대하면서()로 묶어 바인딩합니다. @ tomas-petricek, 의견이 있으십니까? – badbadboy