2014-09-16 4 views
8

을 차단 SPAN하지 않습니다 계산식 "이지만 여전히 거기에 있습니다.왜 계산 표현식은 마지막으로 예를 들어

어떻게 해결할 수 있는지 알고 있지만 컴파일러가이 시나리오를 제한하는 이유를 알고 싶습니다.

좋아 내가이 같은 desugared 생각 몇 가지 fiddeling 후 : 내가 얻을

async.TryFinally(
    async.Bind(
     someting(), (fun() -> 
      async.Bind(sometingElse(), (fun() -> 
       async.Zero())))), (fun() -> printfn "finally")) |> ignore 

: (나는 우리가 cexprs를 쓸 수 있습니다 매우 행복 해요)

에서 :

async { 
    try 
     do! someting() 
     do! sometingElse() 
    finally 
     printfn "finally" 
} 

TryFinally의 두 번째 부분은 cexpr을 지원하지 않습니다.

+0

연습으로이 동작을 이해하려면 워크 플로우를 삭제 해보십시오. 결과적으로 일련의 함수 호출이 이것을 불가능하게하는 것을 보게 될 것이다. – Daniel

+0

@ Vesa.A.J.K : 불가능한 컨셉을 제안하는 것이 아닙니다. 워크 플로우가 현재 금지 된 방식으로 만 가능하다는 것입니다. – Daniel

+0

@ Vesa.AJK 제품을 더 빨리 꺼내기 위해 구현을 단순화하기로 결정한 것이 아니라고 생각합니다. – phoog

답변

7

try-finallyfinally 절에 대한 계산식이있는 표현식은 이미 지원되지 않습니다 (F # 3.1 참조). 그러나 본질적으로 그러한 동작을하는 함수를 구현하는 것은 쉽습니다. 다음은 구현 예입니다.

let tryFinally (body: Async<'x>) (finalize: Async<unit>) : Async<'x> = async { 
    let! result = Async.Catch body 
    do! finalize 
    return match result with 
      | Choice1Of2 value -> value 
      | Choice2Of2 exn -> raise exn 
} 
+0

굉장한 당신도 해결책을 제공했습니다 : – albertjan

+4

취소로 인해 시체가 선매되면이 전화는 확정되지 않습니다. –