xml - HXT: How to use output of an arrow as function argument? -


it's difficult give title question… i'm stuck hxt again. understand want do, i'm not sure how make play nicely arrows. here give simplified description of problem.

function foo takes int , returns arrow:

foo :: arrowxml => int -> xmltree xmltree 

function bar extracts value of attribute:

bar :: arrowxml => xmltree string 

now, need write baz takes map strings ints , returns arrow:

import qualified data.map.lazy m  baz :: arrowxml => m.map string int -> xmltree xmltree 

logic of baz: extract value of attribute bar , in map. if m.lookup returns just x, invoke foo x, otherwise don't (input of arrow goes through unchanged).

afaik every such arrow works filter, in reality arrowxml => xmltree string type means takes xmltree , returns (possibly empty) list of strings. makes me reformulate logic of baz. given input xmltree there may many strings, every string should used integer , first found integer should passed foo. if of them result in nothing, don't anything.

here i've come with:

baz :: arrowxml => m.map string int -> xmltree xmltree baz m = &&& (bar >>> arr (`m.lookup` m)) >>> arr (uncurry f)     f xml nothing  = xml           f xml (just x) = foo x xml -- compiler says:          ^^^ not fast, boy  not deduce (arrowxml (->)) arising use of ‘foo’ context (arrowxml a)   bound type signature              baz :: arrowxml => m.map string int -> xmltree xmltree 

not compiler doesn't it, it's difficult reason too.

if reformulate type signatures bit can line pretty well. since have values coming result of arrow in baz affecting behavior of foo, values need fed foo using arrow instead of typical argument. simplifies things lot, i'll recommend creating foo, foowrapper handles decision itself. correct types you'd have

{-# language arrows, nomonomorphismrestriction #-}  import qualified data.map m import control.arrow.arrowtree import text.xml.hxt.core  foo :: arrowxml => (int, xmltree) xmltree foo = undefined  bar :: arrowxml => xmltree string bar = undefined 

then baz, should expecting both xmltree , string input bar, it's arrow type needs a (string, xmltree) something, , here found simplest implement as

baz :: arrowxml => m.map string int -> (string, xmltree) (maybe int, xmltree) baz m = first $ arr $ flip m.lookup m 

all arrow doing converting string lookup on passed in m.map (assuming given in general environment already). need wrapper feed (maybe int, xmltree) (int, xmltree) if , if maybe int just something. here arrow syntax comes in handy. since we're making decision here requires our arrow arrowchoice, so

foowrapper :: (arrowxml a, arrowchoice a) => (maybe int, xmltree) xmltree foowrapper = proc (lkup, tree) ->     case lkup of         nothing -> returna -< tree         v  -> foo -< (v, tree) 

now can tie overall application nothing more built-in combinators (i discovered returna = arr id, can use instead, think it's easier understand arr id)

program :: (arrowxml a, arrowchoice a) => m.map string int -> xmltree xmltree program m =     bar &&& arr id >>> -- first split input between bar , arr id     baz m          >>> -- feed baz m     foowrapper         -- feed lookup foowrapper can make                        -- decision on how route xmltree 

you don't need worry arrowchoice constraint, arrowxml instances brought in scope text.xml.hxt.core implement arrowchoice.

if you're curious without proc notation, simple case statement turned (i think)

foowrapper :: (arrowxml a, arrowchoice a) => (maybe int, xmltree) xmltree foowrapper =     arr (\(lkup, tree) -> case lkup of         nothing -> left tree         v  -> right (v, tree)) >>>     (returna ||| foo) 

the use of ||| forces implement arrowchoice. while isn't bad, wouldn't call readable , there going on doesn't have actual business logic. once move on more complex situations going explode in complexity well, while proc notation should remain relatively simple.


Comments

Popular posts from this blog

c++ - No viable overloaded operator for references a map -

java - Custom OutputStreamAppender not run: LOGBACK: No context given for <MYAPPENDER> -

java - Cannot secure connection using TLS -