Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 递归搜索记录属性并收集到Haskell中的列表中_List_Haskell_Records - Fatal编程技术网

List 递归搜索记录属性并收集到Haskell中的列表中

List 递归搜索记录属性并收集到Haskell中的列表中,list,haskell,records,List,Haskell,Records,嗨,我想知道如何收集(可能)深度嵌套数据结构的相同属性。以下数据类型为 data PageContent = PageElement { content_type :: String , element :: String , attributes :: Maybe Object , services :: Maybe [ServiceRequest] , body :: Maybe [PageCo

嗨,我想知道如何收集(可能)深度嵌套数据结构的相同属性。以下数据类型为

data PageContent = 
PageElement { content_type :: String
            , element :: String
            , attributes :: Maybe Object
            , services :: Maybe [ServiceRequest]
            , body :: Maybe [PageContent]
            , styles :: Maybe Object
            , scripts :: Maybe Object }
| PageComponent { content_type :: String
                , id :: String
                , tag :: Maybe String
                , args :: Maybe Object
                , services ::Maybe [ServiceRequest]}
| PageConditional { content_type :: String
                  , true :: Maybe [PageContent]
                  , false :: Maybe [PageContent]
                  , condition :: String }
deriving(Show)
所以在我的例子中,我试图收集所有声明的ServiceRequest。元素作为[PageContent]列表传入。我认为使用递归函数是完美的,因为例如,当我点击一个PageElement时,该元素可能有一个_body,它有一个Maybe[PageContent],因此遍历PageElement的_body应该与遍历传入的原始[PageContent]列表相同,因为我从Maybe中提取了它

我很难弄清楚如何将此作为新列表返回

getPageContentServiceRequests :: [PageContent] -> Maybe [ServiceRequest]
因此,我可以没有ServiceRequest,也可以有一个包含1个或多个ServiceRequests的列表。如果以递归方式执行此操作,是否会将两个列表传递给函数?一个是[PageContent],然后是一个空列表,我可以在收集ServiceRequests时递归添加到其中

范例

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

这是正确的方法吗?我觉得当我处理同一类型的列表时,我理解递归概念,但如果我必须用不同的类型构造一个全新的列表,我就不理解递归概念

只要
a
幺半群,a
可能是
幺半群

instance Monoid a => Monoid (Maybe a)
因此,我们可以
map
将每个
PageContent
映射到
可能的[ServiceRequest]
mconcat

PageElement
有一个
services::Maybe[ServiceRequest]
,但在
主体::Maybe[PageContent]
下也可能有更多的
Maybe[ServiceRequest]
s。我们可以在body上使用
getPageContentServiceRequests
,使用
>=
连接将要引入的两个级别的
,并使用
(aka
mappend
)将它们附加到
服务中。我们可以对
PageComponent
PageConditional
执行相同的操作:

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)
导入数据.Monoid
getPageContentServiceRequests::[PageContent]->可能是[ServiceRequest]
getPageContentServiceRequests=mconcat。将getServiceRequests映射到何处
getServiceRequests::PageContent->Maybe[ServiceRequest]
getServiceRequests页面元素{services=services,body=body}=
服务(正文>>=getPageContentServiceRequests)
getServiceRequests页面组件{services=services}=
服务
getServiceRequests页面条件{true=true,false=false}=
(true>>=getPageContentServiceRequests)
(false>>=getPageContentServiceRequests)

可能
抽象零或一,
[]
抽象任意元素。你确定两者都需要吗?你需要区分
只是[]
什么都不知道吗?@Zeta不需要。你的意思是我可以有类型::[PageContent]->[a],其中[a]是[ServiceRequest]或[]空列表?是的,但是你的
PageComponent
PageElement
可以有
服务::[ServiceRequest]
而不是
也许[ServiceRequest]
@Zeta啊,我明白你的意思了。我之所以选择[ServiceRequest],可能是因为它正在解析来自yaml文件的这些信息,在yaml文件中可以存在服务声明,也可以不存在服务声明。所以我想是的,我需要把它分开。我想你指的是函数的返回类型,非常感谢你给出了这个清晰且信息丰富的答案