úÎ!²e¯i/      !"#$%&'()*+,-.AProvides curry/uncurry-like function for any number of parameters(c) David James, 2020 BSD3  Experimental Safe=?@AHV ÙMapWith A "stacked tuple" of four valuesMapWith!A "stacked tuple" of three valuesMapWithA "stacked tuple" of two valuesMapWithA "stacked tuple" of one valueMapWithGiven:a type args& containing n embedded arguments; and a result type rCurryTF args r@ represents the ability to convert either way between functions: fCurried :: each -> argument -> as -> a -> separate ->  parameter -> r; andfUncurried :: ,all-arguments-embedded-in-a-single-parameter -> r.so that:fCurried = curryN fUncurried; andfUncurried = uncurryN fCurried.MapWithTThe type of the (curried) function that can have arguments of the types embedded in args+ applied and that returns a result of type r. For example:.:kind! FnType (Char, (Int, (Bool, ()))) String,FnType (Char, (Int, (Bool, ()))) String :: *= Char -> Int -> Bool -> [Char]MapWith4Embeds a number of separate arguments into a single args parameter, applies args' to a function, and returns the result. For example:Ofn1 (c, (n, (b, ()))) = c : replicate n '1' ++ if b then "hello" else "goodbye"curryN fn1 'x' 3 True "x111hello"&This also support partial application::t curryN fn1 'x''curryN fn1 'x' :: Int -> Bool -> [Char]MapWith"Applies each argument embedded in args? as a separate parameter to a function, and returns the result. For example:Cfn2 c n b = c : replicate n '2' ++ if b then "hello" else "goodbye"#uncurryN fn2 ('x', (3, (True, ()))) "x222hello"MapWithA binary operator for *, so if values a, b and c are embedded in args then f $# args = f a b c MapWithstacks one value MapWithstacks two values MapWithstacks three values MapWithstacks four values MapWiththe application of arg!, followed by the application of moreArgs (recursively), giving rMapWith*the application of zero arguments, giving r    Provides the fmap-like functions(c) David James, 2020 BSD3  Experimental NoneEX®MapWithAn  is (recursively) either: a function (a -> i1 [.. -> in] -> b); oran !InjectedFn a (i1 [.. -> in] -> b) , created by  op When nG is the number of parameters injected by an injector (most commonly 1).MapWithInject "from the left"MapWithInject "from the right"MapWithRepresents a function from a', plus a number of injected values, to b.Used by  (& related), which maps over a /-, injecting the additional values as it goes..Constructed by combining a map function with  s using the  and  operators. The sequence: "(a -> i1 -> i2 -> ... -> in -> b) op1 inj1 op2 inj2 ... opn injnwhere:each op is  or ; andeach inj is an  produces an  a bR, with n injected values (or more if any of the injectors inject multiple values).MapWithAn  Injector a i can be used with  to map over a / containing elements of type a), injecting values according to the type i as it goes.8Injectors have an initial state and a generate function.For each item in the /%, the generate function can use both:the item from the /, andthe current stateto determine both:the new state, andthe injection value(s)"The injection value(s) must be an args (per /), in order for the injector to work with the  and & operators. These can be created by:(recommended) using  ,  , etc;(by nesting the values appropriately e.g (i1, ()) or &(i1, (i2, (i3, (i4, (i5, .. () ..))))); ordefining a new instance of §The first value(s) to inject is/are determined by a first call to the generate function. The first call to the generate function is with the first (if combined with ) or last (if combined with ) item from the / and the initial state. For example:%funnyNext a s = (a + 1, app1 $ a + s)%funnyInjector = Injector funnyNext 17/mapWith ((\_ i -> i) ^-> funnyInjector) [4,8,3] [21,13,12] Call  Initial State  Item  New State  Injection  1  17  4  4+1=5  17+4=21  2  5  8  8+1=9  5+8=13  3  9  3  3+1=4 (ignored)  9+3=12 /mapWith ((\_ i -> i) <-^ funnyInjector) [4,8,3] [13,12,20] Call  Initial State  Item  New State  Injection  1  17  3  3+1=4  17+3=20  2  4  8  8+1=9  4+8=12  3  9  4  4+1=5 (ignored)  9+4=13 IMore usefully, this might allow for e.g. injection of random values, etc.MapWith\the first parameter is a generate function, the second parameter is the initial/prior state.MapWithinject 0 if the item is at the limit:%from the left: if it's the first item%from the right: if it's the last itemelse inject False.Hlet f a l = [a, if l then '*' else ' '] in mapWith (f ^-> isLim) "12345"["1*","2 ","3 ","4 ","5 "]Hlet f a l = [a, if l then '*' else ' '] in mapWith (f <-^ isLim) "12345"["1 ","2 ","3 ","4 ","5*"]MapWithinject the item index:6from the left: the first item is 0, the second 1, etc.;from the right: the last item is 0, the penultimate 1, etc.8let f a b = a : show b in mapWith (f ^-> eltIx) "freddy"["f0","r1","e2","d3","d4","y5"]8let f a b = a : show b in mapWith (f <-^ eltIx) "freddy"["f5","r4","e3","d2","d1","y0"]MapWith]True if an even-numbered (0th, 2nd, 4th, etc) item, counting from the left or from the right.Klet f a e = [a, if e then '*' else ' '] in mapWith (f ^-> evenElt) "012345"["0*","1 ","2*","3 ","4*","5 "]Klet f a e = [a, if e then '*' else ' '] in mapWith (f <-^ evenElt) "543210"["5 ","4*","3 ","2*","1 ","0*"]MapWith"Inject each given element in turn:Lfrom the left: the first element will be injected for the first item in the /.Lfrom the right: the first element will be injected for the last item in the /.9let f a b = [a,b] in mapWith (f ^-> eltFrom "bill") "sue"["sb","ui","el"]9let f a b = [a,b] in mapWith (f <-^ eltFrom "bill") "sue"["sl","ui","eb"]aAs a result of laziness, it is not always an error if there are not enough elements, for example:6drop 1 $ mapWith ((\_ i -> i) <-^ eltFrom [8,2]) "abc"[2,8]MapWitha safe version of  . Injects 1 each given element in turn, or 2 after they've been exhausted.Slet f a b = [a,ch b]; ch = maybe '-' id in mapWith (f ^-> eltFromMay "ben") "sally"["sb","ae","ln","l-","y-"]Slet f a b = [a,ch b]; ch = maybe '-' id in mapWith (f <-^ eltFromMay "ben") "sally"["s-","a-","ln","le","yb"]MapWitha safe version of R. Injects each given element in turn, or the default after they've been exhausted.Alet f a b = [a,b] in mapWith (f ^-> eltFromDef 'X' "ben") "sally"["sb","ae","ln","lX","yX"]Alet f a b = [a,b] in mapWith (f <-^ eltFromDef 'X' "ben") "sally"["sX","aX","ln","le","yb"]MapWithinject 1 the adjacent item:;from the left: the previous item, except for the first itemgfrom the right: the next item, except for the last item. (The "previous from the right" is the "next".)inject 2: if there is no adjacent item (i.e. for the first / last).@let f a b = [a,maybe '-' id b] in mapWith (f ^-> adjElt) "12345"["1-","21","32","43","54"]@let f a b = [a,maybe '-' id b] in mapWith (f <-^ adjElt) "12345"["12","23","34","45","5-"]MapWithlike >, but injects the two adjacent items into separate parameters.Rlet f a b c = [a,ch b,ch c]; ch = maybe '-' id in mapWith (f ^-> adj2Elts) "12345"["1--","21-","321","432","543"]Rlet f a b c = [a,ch b,ch c]; ch = maybe '-' id in mapWith (f <-^ adj2Elts) "12345"["123","234","345","45-","5--"]MapWith.Inject a (left-associative) fold of the items: Item ] Injected Value - from the left / from the right  a0   z `acc` a0  #((z `acc` an) `acc` .. a1) `acc` a0  a1  (z `acc` a0) `acc` a1  (z `acc` an) `acc` .. a1  .. - /  an  #((z `acc` a0) `acc` a1) `acc` .. an   z `acc` an flet f a b = a ++ show b in mapWith (f ^-> foldlElts (\l s -> l + length s) 0) ["every", "good", "boy"]["every5","good9","boy12"]flet f a b = a ++ show b in mapWith (f <-^ foldlElts (\l s -> l + length s) 0) ["every", "good", "boy"]["every12","good7","boy3"]MapWith A variant of  that has no starting value: Item F Injected Value " from the left # from the right  a0  a0  (an `acc` .. a1) `acc` a0  a1   a0 `acc` a1  an `acc` .. a1  .. " #  an  (a0 `acc` a1) `acc` .. an  an )mapWith ((,) ^-> foldl1Elts (-)) [10,1,3][(10,10),(1,9),(3,6)])mapWith ((,) <-^ foldl1Elts (-)) [10,1,3][(10,-8),(1,2),(3,3)]MapWithmaps an  over a / type t , turning a t a into a t b! and preserving the structure of t.Parameters (as defined in the 0) are passed to a map function (embedded in the &), in addition to the elements of the /. MapWithlike 3, but with an .!MapWithlike 4 (which is like 3' but ignores the results), but with an ."MapWithlike 5, but with an #MapWith, from the left.$MapWith, from the right.%MapWith, from the left.&MapWith, from the right.'MapWith Maps over a /G, with an additional parameter indicating whether an item is the first.=let g x f = [if f then '*' else ' ', x] in withFirst g "fred"["*f", " r", " e", " d"](MapWith Maps over a /F, with an additional parameter indicating whether an item is the last.<let g x l = [x, if l then '*' else ' '] in withLast g "fred"["f ","r ","e ","d*"])MapWith Maps over a /W, with additional parameters indicating whether an item is the first or last (or both).\let g x f l = [star f, x, star l]; star b = if b then '*' else ' ' in withFirstLast g "fred"["*f ", " r ", " e ", " d*"]*MapWith !andFirstLast = withFirstLast (,,)+MapWith Maps over a /G, with additional parameters indicating the previous and next elements.7The second (or third) parameter to the map function is 2: when called for the first (or last) item, otherwise it's 1 the previous (or next) item.—let f x prvMay nxtMay = maybe "*" (cmp x) prvMay ++ x ++ maybe "*" (cmp x) nxtMay; cmp x y = show $ compare x y in withPrevNext f ["foo", "bar", "baz"]["*fooGT","LTbarLT","GTbaz*"],MapWith andPrevNext = withPrevNext (,,)MapWith6The elements to inject. There must be enough elements.&  !"#$%&'()*+,&'()*+, !"#$%& 116      !"#$%&'()*+,-./0123450670680190:;0:<=&MapWith-0.2.0.0-7usa1ClyNrFG746pOxpHx3CurryTFMapWithApp4App3App2App1FnTypecurryNuncurryN$#app1app2app3app4 $fCurryTF(,)r $fCurryTF()r Injectable^-><-^ InjectedFnInjectorisLimeltIxevenElteltFrom eltFromMay eltFromDefadjEltadj2Elts foldlElts foldl1EltsmapWithmapWithM mapWithM_ foldMapWithisFirstisLastprevEltnextElt withFirstwithLast withFirstLast andFirstLast withPrevNext andPrevNext$fInjectableInjectedFn$fInjectable->baseData.Traversable Traversableghc-prim GHC.TypesTrue GHC.MaybeJustNothingmapM Data.FoldablemapM_foldMap