Ich versuche, eine Funktion zum Laufen zu bringen, die einen Umschlagtyp auspackt, eine Funktion auf den Inhalt anwendet und einen Umschlagtyp zurückgibt. So ähnlich wie die Bindefunktion eines Burritos.
type Envelope<'a> =
{ Content : 'a
; Errors : string list
}
let (!>) f e =
let {Content=content:'a; Errors=errors} = e
match errors with
| [] -> e : Envelope<'a>
| _ -> f content : Envelope<'b>
Der Fehler ist:
This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type ''b'.
Ich habe das "Gefühl", warum es falsch ist, manchmal kehre ich zurück Envelope<'a>
und manchmal kehre ich zurück Envelope<'b>
.
Wie kann ich das zum Laufen bringen? Ich versuche, es so zu machen, als würde ich eine Bindungsfunktion für beispielsweise einen Optionstyp ausführen:
let (>>=) f o =
match o with
| Some v -> f v
| None -> None
Das Problem ist, dass beide Fälle der Übereinstimmung denselben Typ zurückgeben sollten, da dies sonst im Typsystem keinen Sinn ergibt.
Sie müssen einen neuen Umschlag erstellen, aber ich stelle mir vor, dass das Problem darin besteht, dass Sie f nicht berechnen möchten, wenn Fehler vorliegen. Eine hackige Methode hierfür wäre also:
type Envelope<'a> =
{ Content : 'a
; Errors : string list
}
let (!>) f e =
let {Content=content:'a; Errors=errors} = e
match errors with
| [] -> {Content = Unchecked.defaultof<_>; Errors = e.Errors } : Envelope<'b>
| _ -> f content : Envelope<'b>
Aber das ist nicht was Sie wollen, da Sie den Inhalt verlieren werden.
Der richtige Weg wäre, eine diskriminierte Union anstelle eines Datensatzes zu verwenden, aber ich denke, Sie möchten die Kompensationsfunktion immer dann anwenden, wenn Fehler auftreten. In diesem Fall kann Ihre Kompensationsfunktion daher nicht polymorph sein die ursprüngliche Fehlermeldung.
Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.
Bei Verstößen wenden Sie sich bitte [email protected] Löschen.
Lass mich ein paar Worte sagen