2015-12-18 10 views
18

Sto provando a convertire una stringa in intero utilizzando String.toInt. Tuttavia, quando voglio associare il risultato a una variabile e poi fare qualche semplice matematica con esso ottengo questo errore:Conversione da stringa a int utilizzando la funzione toInt

Function add is expecting the 2nd argument to be:

Int 

But it is:

Result String Int 

Come posso solo estrarre la parte intera del risultato?

risposta

21

toInt può non riuscire nell'analisi. È necessario verificare utilizzando un'istruzione case:

case toInt str of 
    Err msg -> ... -- do something with the error message 
    Ok val -> ... -- val is an Int which you can add 

More about Result here

25

Ecco come fornire la conversione con un valore di default nel caso in cui l'analisi non riesce.

String.toInt "5" |> Result.toMaybe |> Maybe.withDefault 0 
8

Il numero intero può anche essere estratta utilizzando

Result.withDefault 0 (String.toInt "2") 

Si può leggere di più su di esso here

1

Secondo il Elm String reference documentation, se si estraggono un numero da qualche input dell'utente cruda, in genere si desidera utilizzare Result.withDefault per gestire i dati non validi in caso di analisi non riuscita. È possibile catena di questa operazione utilizzando tubi per il codice più pulito:

String.toInt "5" |> Result.withDefault 0 
0

Usa mappa:

answer = Result.map2 (+) (String.toInt "1") (String.toInt "2") 

map2:

Apply a function to two results, if both results are Ok. If not, the first argument which is an Err will propagate through.

di avere il risultato add come una stringa

resultAsString r = 
    case r of 
     Err msg -> msg 
     Ok value -> toString value 

resultAsString answer 

Per rendere le cose più facili è possibile creare una funzione addStrings:

addStrings : String -> String -> Result String Int 
addStrings a b = 
    Result.map2 (+) (String.toInt a) (String.toInt b) 

È possibile anche ottenere via con il tipo Result del tutto:

addStrings : String -> String -> String 
addStrings a b = 
    let 
     r = 
      Result.map2 (+) (String.toInt a) (String.toInt b) 
    in 
    case r of 
     Err msg -> 
      msg 

     Ok value -> 
      toString value 

Testing

import Html exposing (Html, text) 

main : Html msg 
main = 
    text (addStrings "1" "2") 


output 3 
0

Il metodo withDefault ti costringe per definire un valore che può essere utilizzato per i calcoli ma non è sempre possibile stabilire un valore significativo per gli errori. Molto spesso sono necessari tutti i valori possibili e l'impostazione predefinita non è adatta. Qui mi forniscono una funzione di tipo assegno risultato è possibile utilizzare per decidere se si utilizza o meno il valore convertito:

isErrorResult r = 
    case r of 
     Err msg -> 
      True 

     Ok value -> 
      False 

è possibile utilizzarlo in questo modo:

r = String.toInt "20b" 

if isErrorResult r then 
    -- not a valid Interger, abort or whatever 
else 
    -- a good integer, extract it 
    a = Result.withDefault 0 r 
    -- and make good use of it 

il valore default (0 in questo caso) passato a withDefault non ha senso, perché ci siamo assicurati che r non sia un Err.