2017-09-15 4 views
0

동일한 유형의 필드 중 하나 때문에 자체를 호출하는 디코더를 어떻게 구현합니까? 이동일한 유형의 필드 중 하나 때문에 자체를 호출하는 디코더를 어떻게 구현합니까?

결론적으로, 내가 방법을 잘 무한하지 않다 원인

(field "Subscriptions" <| Decode.list providerDecoder) 
(field "Followers" <| Decode.list providerDecoder) 

providerDecoder 그 자체의 관점에서 직접 정의됩니다

providerDecoder : Decoder JsonProvider 
providerDecoder = 
    Decode.map6 JsonProvider 
     (field "Profile" profileDecoder) 
     (field "Topics" <| Decode.list topicDecoder) 
     (field "Links" <| linksDecoder) 
     (field "RecentLinks" <| Decode.list linkDecoder) 
     (field "Subscriptions" <| Decode.list providerDecoder) 
     (field "Followers" <| Decode.list providerDecoder) 

다음 줄

는 문제를 일으키는 JsonProvider 유형을 유지하면서이 오류를 해결할 수 있습니다.

부록 :

type JsonProvider 
    = JsonProvider 
     { profile : JsonProfile 
     , topics : List JsonTopic 
     , links : JsonLinks 
     , recentLinks : List JsonLink 
     , subscriptions : List JsonProvider 
     , followers : List JsonProvider 
     } 

답변

3

당신이 재귀 JSON 디코더를 작성, 당신은 일반적으로 Json.Decode.lazy에 의존해야합니다. 단일 생성자 조합 유형을 사용하고 있기 때문에 당신이 다른 오류 메시지가 일치하지 않는 유형에 대해 팝업 볼 수 있음을 변경하면

(field "Subscriptions" <| Decode.list (Decode.lazy (\_ -> providerDecoder))) 
(field "Followers" <| Decode.list (Decode.lazy (\_ -> providerDecoder))) 

, 그리고 그건 :이 같은 두 줄을 쓸 수 있습니다 이는 레코드를 인수로가집니다 (재귀 레코드 유형을 작성할 때 필요합니다). 이 경우 나는 보통 같은 생성자 기록 유형을 분리 :

type JsonProvider 
    = JsonProvider JsonProviderFields 

type alias JsonProviderFields = 
    { profile : JsonProfile 
    , topics : List JsonTopic 
    , links : JsonLinks 
    , recentLinks : List JsonLink 
    , subscriptions : List JsonProvider 
    , followers : List JsonProvider 
    } 

는 이제 다음, 먼저 JsonProviderFields 기록을 디코딩하는 공급자 디코더를 다시 JsonProvider에 매핑 할 수 있습니다

providerDecoder : Decoder JsonProvider 
providerDecoder = 
    Decode.map6 JsonProviderFields 
     (field "Profile" profileDecoder) 
     (field "Topics" <| Decode.list topicDecoder) 
     (field "Links" <| linksDecoder) 
     (field "RecentLinks" <| Decode.list linkDecoder) 
     (field "Subscriptions" <| Decode.list (Decode.lazy (\_ -> providerDecoder))) 
     (field "Followers" <| Decode.list (Decode.lazy (\_ -> providerDecoder))) 
     |> Decode.map JsonProvider