I'm sure one reason so many people have particular trouble with them is because, according to the survey, the vast majority of them come from a dynamically-typed language where you'd just go `user = JSON.parse(string)`.
I think a lot of people would be helped by tacking a bunch of real-world examples onto the actual Json.Decoder docs like how to decode `[1, [3, 5], 7, 9]` (nested range) into `[1, 3, 4, 5, 7, 9]`. One issue is that it's pretty hard to derive understanding from just function signatures, so a dozen quick-start / cookbook examples gives people something to chew on.
Combinators are really good at forbidding runtime errors which is a central theme of Elm, but it comes at the expense of a steeper learning curve than the weaker alternatives that come to mind: reflection and manual descent.