Ответ 1
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. Однако, когда я хочу привязать результат к переменной, а затем выполнить некоторую простую математику, я получаю эту ошибку:
Функция
add
ожидает второго аргумента:Int
Но это:
Result String Int
Как я могу просто извлечь целую часть результата?
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
имеет смысла, потому что мы убедились, что r
не является Err
.
Использовать карту:
answer = Result.map2 (+) (String.toInt "1") (String.toInt "2")
map2:
Примените функцию к двум результатам, если оба результата Ок. Если нет, то первый аргумент, который является Err, будет распространяться.
иметь результат 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
Вы можете сделать это, как показано ниже.
---- Elm 0.19.0 ----------------------------------------------------------------
Read <https://elm-lang.org/0.19.0/repl> to learn more: exit, help, imports, etc.
--------------------------------------------------------------------------------
> parseInt string = String.toInt string
<function> : String -> Maybe Int
> resultParseInt string = \
| Result.fromMaybe ("error parsing string: " ++ string) (parseInt string)
<function> : String -> Result String Int
> resultParseInt "12"
Ok 12 : Result String Int
> resultParseInt "12ll"
Err ("error parsing string: 12ll") : Result String Int
>
Я немного изменил ответы парней, так как это похоже на тип Maybe
isErrorResult : String -> Bool
isErrorResult r =
case String.toInt r of
Nothing -> True
Just value -> False