2016-11-22 9 views

ответ

2

Вы можете создать свой собственный декодер с помощью succeed и fail от Json.Decode. Я изменил приведенный ниже порядок аргументов, чтобы сделать его связным.

Редактировать: Разделяемый декодер касается проблем.

import Json.Decode as Json 
import Result 


-- // This is a Result helper function that could be used elsewhere. 
-- // Currently, there is no Result.either in Elm core. 
eitherR : (x -> b) -> (a -> b) -> Result x a -> b 
eitherR fErr fOk result = 
    case result of 
     Err x -> 
      fErr x 

     Ok a -> 
      fOk a 


customDecoder : (a -> Result String b) -> Json.Decoder a -> Json.Decoder b 
customDecoder fResult decoder = 
    decoder |> Json.andThen (fResult >> eitherR Json.fail Json.succeed) 

Подключив это на связанный вопрос ...

let number = 
    Json.oneOf [ Json.int, Json.string |> customDecoder String.toInt ] 

Вот другой пример использования. Это версия onChange, которая преобразует значение в целое число. В основном полезно для select, когда вы знаете, что значение параметра - Int.

import Html 
import Html.Attributes exposing (..) 
import Html.Events exposing (..) 
import String 


onChangeInt : (Int -> msg) -> Attribute msg 
onChangeInt fMsg = 
    on "change" (targetValue |> customDecoder String.toInt |> Json.map fMsg) 

Обратите внимание, что targetValue определяется в модуле Html.Events:

targetValue : Decoder String 
4

Один из способов сделать это (как из Эого 0,18 и ядра 5.0) будет выглядеть так:

stringIntDecoder : Decoder Int 
stringIntDecoder = 
    Json.Decode.map (\str -> String.toInt (str) |> Result.withDefault 0) Json.Decode.string 

String.toInt функция из стандартной библиотеки принимает строку и пытается преобразовать его в целое число, возвращая результат. Result.withDefault делает то, что подразумевает его название - вы даете ему какое-то значение по умолчанию и результат, а если результат Ok x, вы получаете x, но если это Err _, вы получаете заданное по умолчанию значение, указанное здесь 0. Вместо этого вы можете написать функцию для обработки Результат, если вам нравится, и вместо этого передайте эту функцию.

+0

Спасибо, но я не хочу, по умолчанию, я хочу, чтобы потерпеть неудачу, если это не получится! – vitiral

+0

@vitiral Перейдите в свою собственную функцию обработки результатов там. –

0

Учитывая, что в комментарии к другому ответу вы заявляете о необходимости принять возможный отказ, вы можете использовать «Может».

stringIntDecoder : Decoder (Maybe Int) 
stringIntDecoder = 
    Json.Decode.map (String.toInt >> Result.toMaybe) Json.Decode.string 

Или

stringIntDecoder : Decoder (Result String Int) 
stringIntDecoder = 
    Json.Decode.map (String.toInt) Json.Decode.string 
+0

, но это приведет к тому, что поле будет «Nothing» - это не вызовет ошибку декодера! ('Decode.fail') – vitiral

+0

, то просто пропустите' Result.toMaybe' –

+0

, который не вводит проверку. – vitiral

 Смежные вопросы

  • Нет связанных вопросов^_^