MyNixOS website logo
Description

mapWith: like fmap, but with additional parameters (isFirst, isLast, etc)

fmap over Traversables (including lists), but pass additional parameters to the map function, such as isFirst, isLast, prevElt, nextElt, index from start or end, custom params. For examples see https://github.com/davjam/MapWith/blob/master/doc/examples.hs

MapWith Stackage version Hackage version build status

mapWith: like fmap, but can "inject" additional parameters such as whether first (or last) element, etc.

Background

I often want to map over a list, but do something slightly different with the first or last element.

For a long time I used markbounds, but also wanted something that:

  • works on structures other than lists (mapWith works on all Traversable types);
  • can provide additional types of parameter (not just first/last), such as:
    • index from start/end;
    • the previous/next element; and
  • makes it easy to create new types of parameter to provide; and
  • can provide any number of separate parameters to a function (not just a 3-tuple).

So, after only 2 years, I built a small library to do all of these.

Examples

Passing a "standard combination" of isFirst and isLast parameters:

let g x f l = [star f, x, star l]; star b = if b then '*' else ' '
in withFirstLast g "fred"
["*f ", " r ", " e ", " d*"]

Passing a custom combination of different types of parameter (the index from the start, whether it's the last element, and elements from another list applied from the right):

let g x n l e = concat [[x], show n, if l then "*" else "-", e]
in mapWith (g ^-> eltIx & isLast <-^ eltFrom ["x","yy","z","zzzz","y"]) "fred"
["f0-zzzz","r1-z","e2-yy","d3*x"]

More examples are here.

Questions/Doubts

Note that this is my first library and my first use of cabal, so I've probably done some dumb things.

Some things I wonder:

  • Doesn't this already exist? (It feels like it should!)
  • Should I name it Data.Traversable.MapWith? Or are such names "reserved" for "official" libraries, or something? Would this name impact my own file/directory structures?

Future Work

Areas for potential improvement in later releases:

  • Performance investigations and hopefully improvements, in particular:

    • fusion for eltFrom Injectors (unlikely, given the reasons it's not possible for zipWith, but we'll see).
    • enhancements for "stateful" "from the right" Injectors (unlikely, given this).
  • CurryTF: avoid tuples? (The tuple (7, ()) is interpreted by CurryTF as an application of a single value 7, but by Data.Tuple.Curry as two values: 7 and (), which I think is slightly more confusing than it needs to be.)

Metadata

Version

0.2.0.0

Platforms (75)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    WASI
    Windows
Show all
  • aarch64-darwin
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64_be-none
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-darwin
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-darwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • vc4-none
  • wasm32-wasi
  • wasm64-wasi
  • x86_64-cygwin
  • x86_64-darwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-windows