tag:blogger.com,1999:blog-7094652.post1790264824398560607..comments2024-03-23T14:36:09.980+00:00Comments on Neil Mitchell's Blog (Haskell etc): Concise Generic QueriesNeil Mitchellhttp://www.blogger.com/profile/13084722756124486154noreply@blogger.comBlogger8125tag:blogger.com,1999:blog-7094652.post-14759812764576492002009-03-26T10:53:00.000+00:002009-03-26T10:53:00.000+00:00I worded that third paragraph poorly. The [] versi...I worded that third paragraph poorly. The [] version will search search for other matching OrgHeaderPs when the first one with the right name doesn't have a matching ParagraphP. The conversion to Maybe cuts short this further searching.<BR/><BR/>If we have the guarantees mentioned in my previous comment, the shortcutting done by conversion to Maybe will be more efficient, because it'll save us from searching through the whole tree.<BR/><BR/>But as far as I know, it's not something library-specific. If needed, insert listToMaybe in the Uniplate version if you want the notationally more cumbersome, but non-backtracking version.<BR/><BR/>So I think in this case, I think it's just a different interpretation of the problem.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-7094652.post-17536034469911098152009-03-26T10:44:00.000+00:002009-03-26T10:44:00.000+00:00There's actually a couple of differences in that t...There's actually a couple of differences in that they both search for something different, due to the backtracking nature of [].<BR/><BR/>The Maybe version will only consider the first OrgHeaderP with the right name, and only return Just when the first ParagraphP inside that OrgHeaderP matches "Description".<BR/><BR/>The [] version will consider all OrgHeaderPs with the right name, and return Just if any ParagraphP inside matches "Description". It'll return Just the text of the first matching ParagraphP inside the first matching OrgHeaderP.<BR/><BR/>If we somehow have the guarantees (due to file structure or other) that if we have a "Description", it's in the first ParagraphP, and the names of OrgHeaderP are unique, it's the same thing. If we cannot guarantee such a thing, it depends on what you're looking for.<BR/><BR/>Of course, the same holds for the Uniplate version, which can, in a similar way, be rewritten using Maybe. Just throw in some extra listToMaybes.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-7094652.post-74213578395398762722009-03-25T20:33:00.000+00:002009-03-25T20:33:00.000+00:00José: Thanks for the Maybe version of SYB, that do...José: Thanks for the Maybe version of SYB, that does follow the same pattern now. I realised there were differences in the operations with the Either vs Maybe, but couldn't be bothered to change/test the SYB again.<BR/><BR/>Joeri: Is there any reason for EMGM to use Maybe over list comprehensions? You revised EMGM seems much clearer.Neil Mitchellhttps://www.blogger.com/profile/13084722756124486154noreply@blogger.comtag:blogger.com,1999:blog-7094652.post-28643197511129110012009-03-23T11:53:00.000+00:002009-03-23T11:53:00.000+00:00You are right in that Uniplate's "univers...You are right in that Uniplate's "universeBi" and EMGM's "collect" are the same. EMGM's solution used Maybe directly, instead of keeping things in [], so list comprehensions couldn't be used. However, since the EMGM solution uses "firstr" only to convert lists to Maybe, you could use listToMaybe as well. We can keep using [] and rely on lazyness such that the outermost listToMaybe will only actually force calculation of the first element in the comprehension, instead of cutting off at the first element with firstr inside "firstPara", we get:<BR/><BR/>projDesc :: String -> OrgFileP -> Maybe String<BR/>projDesc name file = listToMaybe $<BR/> [ str<BR/> | OrgHeadingP _ x ys <- G.collect file, x == name<BR/> , ParagraphP y <- G.collect ys, str ~= "Description"<BR/> ]<BR/><BR/>Which is exactly the same as the Uniplate version (barring (~=) and isPrefixOf, but that's not the point).Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-7094652.post-77208037873476728762009-03-23T11:14:00.000+00:002009-03-23T11:14:00.000+00:00Hello Neil. Nice post.The SYB solution is working ...Hello Neil. Nice post.<BR/><BR/>The SYB solution is working with Either to provide feedback when the element is not found. The feedback is better than that provided by the Uniplate or EMGM versions, at the cost of some extra lines. Using Maybe we can get a shorter version:<BR/><BR/>getP14Desc :: OrgElement -> Maybe String<BR/>getP14Desc org = everything mplus (Nothing `mkQ` findP14) org >>=<BR/> everything mplus (Nothing `mkQ` findDesc)<BR/> <BR/> where<BR/> findP14 h@(Heading {headingName=name})<BR/> | name == "Project14" = Just h<BR/> findP14 _ = Nothing<BR/><BR/> findDesc (Paragraph {paragraphText=text})<BR/> | text =~ "Description" = Just text<BR/> findDesc _ = Nothing<BR/><BR/><BR/>Nevertheless, I agree that here the Uniplate style is the clearest.dreixelhttps://www.blogger.com/profile/07260638525732719462noreply@blogger.comtag:blogger.com,1999:blog-7094652.post-58239992179413119232009-03-21T15:17:00.000+00:002009-03-21T15:17:00.000+00:00meteficha: Should be all fixed now. In future I...meteficha: Should be all fixed now. In future I'll try and remember to avoid < in the code snippets without escaping.Neil Mitchellhttps://www.blogger.com/profile/13084722756124486154noreply@blogger.comtag:blogger.com,1999:blog-7094652.post-36321126283855865542009-03-21T13:38:00.001+00:002009-03-21T13:38:00.001+00:00I mean, use "& l t ;" ;)I mean, use "& l t ;" ;)metefichahttps://www.blogger.com/profile/15462135710203643022noreply@blogger.comtag:blogger.com,1999:blog-7094652.post-80437951349172346152009-03-21T13:38:00.000+00:002009-03-21T13:38:00.000+00:00Hey, Neil! Could you please try to use '<&#...Hey, Neil! Could you please try to use '<' instead of '<' in the HTML? My browser handles it but my RSS reader is stricter.<BR/><BR/>Thanks!metefichahttps://www.blogger.com/profile/15462135710203643022noreply@blogger.com