Преобразование строки в int с помощью функции toInt

Я пытаюсь преобразовать строку в целое число, используя строку.toInt. Однако, когда я хочу привязать результат к переменной, а затем сделать с ней простую математику, я получаю эту ошибку:

функции add ожидает, что 2-й аргумент будет:

Int

а это:

Result String Int

как я могу просто извлечь целую часть результата?

6 ответов


toInt может не выполнить синтаксический анализ. Вам нужно проверить его, используя оператор case:

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

подробнее о результате здесь


вот как предоставить преобразование со значением по умолчанию в случае сбоя синтаксического анализа.

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

целое число также можно вытащить с помощью

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

вы можете прочитать больше об этом здесь


по словам Elm string справочная документация, если вы извлекаете число из некоторого необработанного пользовательского ввода, вы обычно хотите использовать Result.withDefault для обработки плохих данных в случае сбоя синтаксического анализа. Вы можете связать эту операцию с помощью труб для более чистого кода:

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

на withDefault метод заставляет вас определить значение, которое может использоваться для вычислений, но не всегда возможно установить значение, значимое для ошибок. Чаще всего вам нужны все возможные значения, а по умолчанию не подходит. Здесь я предоставляю функцию проверки типа результата, которую вы можете использовать, чтобы решить, используете ли вы преобразованное значение:

isErrorResult r =
    case r of
        Err msg ->
            True

        Ok value ->
            False

вы можете использовать его как это:

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

на default значение (0 в этом случае) передано в withDefault is бессмысленно, потому что мы убедились, что r - это не Err.


использовать карту:

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

map2:

применить функцию к двум результатам, если результаты будут ОК. Если нет, то первый аргумент, который является ошибкой, будет распространяться.

иметь add результат в виде строки

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

resultAsString answer

чтобы сделать вещи проще, вы можете создать addStrings функция:

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

вы даже можете уйти с Result тип всего:

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

тестирование

import Html exposing (Html, text)

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


output 3