2016-12-27 3 views
4

dire que nous avons une fonction très simpleToString lance NullReferenceException pour valeur unitaire()

let fn a = a.ToString() 

Il est le type se déduit que a -> string Cependant, le passage d'une valeur unitaire à la fonction des résultats dans un NullReferenceException.

En cas de fonctions simples comme ci-dessus, cela pourrait être contourné facilement, mais je suis en fait dans un scénario plus complexe:

let eitherToHttp e = 
    match e with 
    | Either.Ok v ->  OK (v.ToString()) 
    | Either.Bad reason -> reasonToErrorCode reason 

Le type de c'est Either<'a, RejectReason> -> WebPart (ce WebPart et Either sont en réalité est non pertinent ici)

Dans un scénario où le type de e est Either<unit, RejectReason> la fonction jette exactement comme dans le scénario simple.

Comment puis-je surmonter cela d'une manière agréable? Faut-il en déduire que les types sont génériques si, en fait, cela ne fonctionne pas pour TOUS les types?

+3

L'unité est représentée par la constante 'null' à l'exécution, donc vous ne pouvez naturellement pas appeler des méthodes. –

Répondre

3

Vous pouvez faire quelque chose comme ceci:

let fn a = match box a with 
      | null -> "" 
      | _ -> a.ToString() 

Cette compile jusqu'à un chèque nul sur a avant d'essayer d'appeler ToString.

+0

S'il vous plaît lire mon commentaire à la réponse de Mark pour savoir pourquoi celui-ci a été accepté. –

+0

Pour être honnête, vous pourriez mettre en ligne sa solution et cela pourrait fonctionner mieux. Vous pouvez l'essayer – Ringil

+0

Je l'ai essayé il y a un instant. Il semble que l'utilisation de «inline» soit plutôt contagieuse. L'utiliser fait aussi que la fonction qui appelle une fonction 'inline' est' inline', ou l'empêche d'être générique. Regardez dans ma question la fonction 'anyToHttp' que j'aimerais être aussi générique que possible. Inlining il semble en quelque sorte pas adapté à moi (mais peut-être que je me trompe). –

6

Utilisez le haut-string fonction au lieu d'appeler ToString sur l'objet:

> string 42;; 
val it : string = "42" 
> string();; 
val it : string = "" 
+0

Je déplace la balise de réponse acceptée, puisque l'autre réponse, bien que moins élégante produit une fonction générique, alors que l'opérateur 'string' semble être limité, veuillez voir mon autre question SO pour les détails: http: // stackoverflow .com/questions/41371190/type-inférence-sur-tostring-vs-string-operator –