2017-11-24 18 views
1

안녕하세요 저는 깊이 중첩 된 데이터 구조와 동일한 attibute를 수집하는 방법을 얻으려고합니다. 다음 데이터 형식은 다음과 같습니다.재귀 적으로 레코드 속성을 검색하고 Haskell의 목록에 수집하십시오.

그래서 제 경우에는 선언 된 모든 ServiceRequest를 수집하려고합니다. 요소는 [PageContent] 목록으로 전달됩니다. 재귀 함수를 사용하는 것이 완벽 할 것이라고 생각합니다. 예를 들어 PageElement를 클릭했을 때 요소에 [PageContent]가있는 _body가있을 수 있기 때문에 PageElement의 _body를 통과하는 것이 원래 [ PageContent]리스트가 전달되었을 때, 아마 내가 추출했을 것이다.

나는 힘든 시간 나는 그래서 내가 어떤 서비스 요청이없는 수있는 새로운 목록

getPageContentServiceRequests :: [PageContent] -> Maybe [ServiceRequest] 

으로이 반환 또는 내가 1 이상의 ServiceRequests의 목록을 가질 수있는 방법을 알아내는 있습니다. 이 작업을 재귀 적으로 수행하면 함수에 두 개의 목록을 전달하게됩니까? 하나는 [PageContent]이고, 그런 다음 ServiceRequests를 수집하는 동안 재귀 적으로 추가 할 수있는 빈 목록?

예를

getPageContentServiceRequests (x:xs) (y:ys) = 
    case (isJust (body x)) of 
     True -> y : getPageContentServiceRequests fromJust (body x) ys 

이 올바른 접근 방식을 수 있을까요? 같은 유형의 목록으로 작업 할 때 재귀 개념을 이해하지만 다른 유형의 완전히 새로운 목록을 작성해야하는 것은 아닙니다.

+1

는 Maybe' '는 0 또는 1 추상화'[] '임의의 요소를 추상화한다. 둘 다 필요하신가요? 'Just [] '와'Nothing'을 구별해야합니까? – Zeta

+0

@Zeta 아닙니다. 당신은 타입을 가질 수 있다는 것을 의미합니다 : : [PageContent] -> [a] [a]는 [ServiceRequest]이거나 [] 빈리스트입니까? – Donna

+0

네,하지만 PageComponent 또는 PageElement는'Maybe [ServiceRequest]'대신'services :: [ServiceRequest]'를 가질 수 있습니다. – Zeta

답변

2

Maybe a는 한 aMonoid입니다 같은 Monoid입니다 :

instance Monoid a => Monoid (Maybe a) 

따라서, 우리가 할 수 mapPageContentMaybe [ServiceRequest]mconcat을 A와.

services :: Maybe [ServiceRequest]이지만, body :: Maybe [PageContent] 아래에 더 많은 Maybe [ServiceRequest]을 가질 수 있습니다. 본문에 getPageContentServiceRequests을 사용하고 을 사용하여 Maybe의 두 단계를 결합하고 <> (별칭 mappend)을 사용하여 services을 추가 할 수 있습니다. 우리 PageComponentPageConditional과 동일한 작업을 수행 할 수

import Data.Monoid 

getPageContentServiceRequests :: [PageContent] -> Maybe [ServiceRequest] 
getPageContentServiceRequests = mconcat . map getServiceRequests where 

    getServiceRequests :: PageContent -> Maybe [ServiceRequest] 
    getServiceRequests PageElement { services=services, body=body } = 
    services <> (body >>= getPageContentServiceRequests) 
    getServiceRequests PageComponent { services=services } = 
    services 
    getServiceRequests PageConditional { true=true, false=false } = 
    (true >>= getPageContentServiceRequests) <> 
    (false >>= getPageContentServiceRequests) 
+0

대단히이 명확하고 유익한 답변을 주셔서 감사합니다 – Donna