Conversión de cadena a int usando la función toInt


Estoy tratando de convertir una cadena a entero usando String.toInt. Sin embargo, cuando quiero enlazar el resultado a una variable y luego hacer algunas matemáticas simples con ella obtengo este error:

La función add espera que el segundo argumento sea:

Int

Pero es:

Result String Int

¿Cómo puedo simplemente extraer la parte entera del resultado?

 23
elm
Author: Matthias Braun, 2015-12-18

6 answers

ToInt puede fallar en el análisis. Necesitas comprobarlo usando una sentencia case:

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

Más sobre Result aquí

 26
Author: Chad Gilbert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-18 19:47:25

Aquí está cómo proporcionar la conversión con un valor predeterminado en caso de que el análisis falle.

String.toInt "5" |> Result.toMaybe |> Maybe.withDefault 0
 29
Author: d13,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-28 17:53:02

El entero también se puede extraer usando

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

Puedes leer más al respecto aquí

 8
Author: Sumit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-21 06:17:12

De acuerdo con la documentación de referencia de la cadena Elm , si está extrayendo un número de una entrada de usuario sin procesar, normalmente querrá usar Result.withDefault para manejar datos defectuosos en caso de que el análisis falle. Puede encadenar esta operación usando pipes for cleaner code:

String.toInt "5" |> Result.withDefault 0
 3
Author: akdev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-11 20:15:09

El método withDefault obliga a definir un valor que se puede utilizar para los cálculos, pero no siempre es posible establecer un valor que sea significativo para los errores. La mayoría de las veces se necesitan todos los valores posibles, y por defecto no se ajusta. Aquí proporciono una función de verificación de tipo de resultado que puede usar para decidir si usa o no el valor convertido:

isErrorResult r =
    case r of
        Err msg ->
            True

        Ok value ->
            False

Puedes usarlo así:

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

El valor default (0 en este caso) pasado a withDefault no tiene sentido, porque nos aseguramos de que r no es un Err.

 1
Author: Alfgaar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-17 01:05:37

Utilice el mapa:

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

Map2:

Aplique una función a dos resultados, si ambos resultados están bien. Si no, el el primer argumento que es un Error se propagará a través.

Para tener el resultado add como una cadena

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

resultAsString answer

Para facilitar las cosas puedes crear una función addStrings:

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

Incluso puedes salirte con la tuya con el tipo Result por completo:

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

Pruebas

import Html exposing (Html, text)

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


output 3
 0
Author: Alfgaar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-17 00:28:13