2017-11-06 17 views
3
elm-compiler 저장소 재귀 형 별명 힌트에서 작업

이 번 용액의 종류 서명을 산출 나열 빈 응답 목록).계수 요소

저는 현재 솔루션이 필요한 것보다 훨씬 복잡해 보이지만 그러한 목록의 요소 수를 계산하는 데 관심이 있습니다.

count : List Comment -> Int 
count comments = 
    let 
     responses = 
      List.concatMap (\c -> flatList c) comments 
    in 
    List.length responses 


flatList : Comment -> List Comment 
flatList root = 
    let 
     rest = 
      case root.children of 
       Just responseList -> 
        List.concatMap (\child -> flatList child) <| unwrapResponses responseList 
       Nothing -> 
        [] 
    in 
    root :: rest 

unwrapResponses : Responses -> List Comment 
unwrapResponses responses = 
    case responses of 
     Responses comments -> 
      comments 

효과적으로, 이는 각각의 서브리스트를 언랩 Responses 재귀을 병합. 그런 다음 각 부모 Comments에 대해 Responses 플랫 목록을 연결하고 마지막으로이 목록의 길이를 가져옵니다.

이 평평한 목록에는 아무런 쓸모가 없으므로 목록을 통해 반복해서 각 List.length을 계산 한 다음 결과를 배분하거나 합계하는 것이 좋습니다 (또는 전체 요소 수를 검색하는 다른 방법을 사용하십시오). 그러나 나는 어떻게 flatList 결과를 반환하지 않고 그러한 솔루션을 생성하는지 확신 할 수 없습니다.

답변

2

댓글에 특수화 된 접기 기능이 필요한 것 같습니다. 접는 (folding)은 요소와 일종의 누적 기 값을 받아들이는 함수로 구조의 모든 요소를 ​​방문하여 단계별로 상태를 유지할 수있는 아이디어입니다.

사이드 노트 : 나는 빈리스트 때문에 당신이 Responses 대신 Maybe Responses로 의견 responses을 정의하는 것이 좋습니다 및 Nothing 정말 같은 일을 나타냅니다.

당신은 이런 댓글의 목록의 foldl을 정의 할 수 있습니다 :

foldl : (Comment -> b -> b) -> b -> List Comment -> b 
foldl f = 
    List.foldl 
     (\c acc -> 
      case c.responses of 
       Responses responses -> 
        foldl f (f c acc) responses 
     ) 

처음 함수로 주석 노드를 방문 의미, 모든 아이들이 따라 결과를 축적, 왼쪽에서 오른쪽으로 방법.

길이를 결정하는 데 사용하려면, 당신은 단순히 의견을 무시하고 길을 따라 카운터를 증가 :

length : List Comment 
length = 
    foldl (\_ acc -> acc + 1) 0 

당신은 definition of List.length가 구현을위한 foldl의 같은 생각을 사용하고 있음을 알 수 있습니다.

+0

설명해 주셔서 감사합니다. 사이드 노트 또한 많은 의미를 갖기 때문에 통찰력에 다시 한번 감사드립니다. – Geodesic