Search code examples
jsonfunctional-programmingdecodeelm

How can I apply the Result.withDefault function to a function that produces a Result


I've got this function that decodes JSON

type alias Item =
    { title : String
    , description : String
    , price : Float
    , imageUrl : String
    }

itemDecoder : Json.Decode.Decoder Item
itemDecoder =    
    D.map4 ItemData
        (D.field "title" D.string)
        (D.field "description" D.string)
        (D.field "price" D.float)
        (D.field "imageUrl" D.string)

decodeItem : Json.Decode.Value -> Item
decodeItem =
    Json.Decode.decodeValue itemDecoder

The error I get from the compiler is that decodeItem produces a

Json.Decode.Value -> Result Json.Decode.Error Item

instead of a

Json.Decode.Value -> Item

How can I wrap the output of decodeItem with a Result.withDefault so that it produces a valid item or it returns an empty Item. The empty Item would be the first argument to Result.withDefault.


Solution

  • Given that you have a function which returns an empty Item, for example emptyItem, you just need to perform the steps you've described:

    • Wrap the output of decodeItem with a Result.withDefault
    • The empty Item would be the first argument to Result.withDefault

    As a result:

    decodeItem : D.Value -> Item
    decodeItem value =
        Result.withDefault emptyItem (D.decodeValue itemDecoder value)
    

    emptyItem can be a function which returns Item record with default values, for example:

    emptyItem : Item
    emptyItem = Item "" "" 0 ""
    

    Or some reasonable defaults, that make sense to you