2009-04-03 5 views
3

J'utilise F # v 1.9.6.2, et je l'ai défini une expression de calcul très simple:Expression de calcul n'exécute laissez pas

type MaybeBuilder() = 
    member this.Let(x, f) = 
     printfn "this.Let: %A" x 
     this.Bind(Some x, f) 
    member this.Bind(x, f) = 
     printfn "this.Bind: %A" x 
     match x with 
     | Some(x) when x >= 0 && x <= 100 -> f(x) 
     | _ -> None 
    member this.Delay(f) = f() 
    member this.Return(x) = Some x 

let maybe = MaybeBuilder() 

J'ai saupoudré des déclarations d'impression dans le code de dire moi quelles méthodes sont appelées dans une expression de calcul. Quand j'exécutez l'instruction suivante:

maybe { 
    let x = 12 
    let! y = Some 11 
    let! z = Some 30 
    return x + y + z 
} 

Je me attends à la console pour imprimer les éléments suivants:

this.Let 12 
this.Bind Some 12 
this.Bind Some 11 
this.Bind Some 30

Mais mes résultats réels sont les suivants:

this.Bind: Some 11 
this.Bind: Some 30

En d'autres termes, F # ne semble pas exécuter le membre Let. Lorsque je réécris Let pour lancer une exception, le code s'exécute sans exception. En outre, lorsque je commente entièrement le membre Let, je ne pas obtenir un message d'erreur indiquant The field, constructor or member 'Let' is not defined et le code s'exécute comme prévu.

(je l'ai essayé enquêter sur le code avec réflecteur, mais comme cela est généralement le cas, décompilé F # est mutilée au-delà de la lisibilité.)

Il semble que le spec for computation expressions a changé. Les liaisons let ne sont-elles plus traitées comme du sucre de syntaxe et les membres Let ne sont-ils plus requis dans les workflows de calcul?

Répondre

4

Vous avez eu la réponse vous-même. De l'F# spec qui décrit comment les expressions de calcul sont traduits:

{| let binds in cexpr |}C = let binds in {| cexpr |}C) 

Donc non, vous n'avez pas besoin de définir explicitement laisser plus, il est traduit par le compilateur.

Mise à jour: cette modification est mentionnée dans the detailed release notes of the September CTP.

+0

Merci :) j'ai lu dans les notes de publication avant de poster ma question, mais n » était pas. t entièrement sûr puisque 100% des exemples démontrant la peut-être monade définissent un membre Let. – Juliet

0

Correct - vous ne pouvez plus fournir une liaison pour let :(

+0

Pourquoi le visage triste? Je veux dire, je peux vous voir perdre de la flexibilité, mais aviez-vous un cas d'utilisation pour cela? À première vue, il semble plus déroutant qu'utile. –

+0

Je ne pense pas que ce soit une mauvaise chose, personnellement, je n'aime pas l'idée de redéfinir le sens de let. – Juliet

+0

Eh bien la dernière fois que j'ai vérifié (il y a des mois), était d'écrire un flux de travail combo qui faisait un "async" (spécifique à l'application) et qui avait des possibilités de résiliation anticipée sur chaque instruction exécutée. Pas difficile de contourner, juste aurait été mignon. Je n'ai certainement pas analysé comme le F # a :). – MichaelGG