From ffd02244cd4dff35c41f87a4ccde860928cfdc79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C5=82awomir=20=C5=9Aled=C5=BA?= Date: Tue, 15 Aug 2017 23:43:11 +0200 Subject: [PATCH] Initial import --- examples/example.sh | 49 +++++++++ src/fun.sh | 236 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 285 insertions(+) create mode 100755 examples/example.sh create mode 100755 src/fun.sh diff --git a/examples/example.sh b/examples/example.sh new file mode 100755 index 0000000..a2dbba8 --- /dev/null +++ b/examples/example.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +source ../src/fun.sh + +seq 1 4 | sum +seq 1 4 | product +factorial 4 +seq 1 4 | scanl lambda a b . 'echo $(add $a $b)' +echo map mul +seq 1 4 | map lambda a . 'echo $(mul $a 2)' +echo map sub +seq 1 4 | map lambda a . 'echo $(sub $a 2)' +echo map add +seq 1 4 | map lambda a . 'echo $(add $a 2)' +echo map div +seq 1 4 | map lambda a . 'echo $(div $a 2)' +echo map mod +seq 1 4 | map lambda a . 'echo $(mod $a 2)' +echo 'list & head' +list 1 2 3 4 5 | head +list {1..2} | append {3..4} | prepend {99..102} +list {1..2} | unlist +list {1..10} | head +list {1..10} | drop 7 +list {1..10} | take 3 +list {1..10} | last +list {1..10} | map λ a . 'echo $(mul $a 2)' + +id() { + λ x . '$x' +} + +id <<< 'echo :)' + +foobar() { + product | λ l . 'list {1..$l}' | sum | md5sum +} + +list {1,2,3} | foobar + +echo -n abcdefg | revers_str # gfedcba +echo -n abcdefg | splitc | join , '[' ']' # [a,b,c,d,e,f,g] +echo -n abcdefg | splitc | revers | join , '[' ']' # [g,f,e,d,c,b,a] + +echo -n ' abcdefg' | splitc | foldr lambda a b . 'echo $a$b' # gfedcba + +echo 'ls' | try λ cmd status ret . 'echo $cmd [$status]; echo $ret' + +list {1..10} | filter lambda a . '[[ $(mod $a 2) -eq 0 ]] && ret true || ret false' | join , '[' ']' # [2,4,6,8,10] diff --git a/src/fun.sh b/src/fun.sh new file mode 100755 index 0000000..263b7f3 --- /dev/null +++ b/src/fun.sh @@ -0,0 +1,236 @@ +#!/bin/bash + +drop() { + command tail -n +$(($1 + 1)) +} + +take() { + command head -n ${1} +} + +tail() { + drop 1 +} + +head() { + take 1 +} + +last() { + command tail -n 1 +} + +list() { + for i in "$@"; do + echo "$i" + done +} + +unlist() { + cat - | xargs +} + +append() { + cat - + list "$@" +} + +prepend() { + list "$@" + cat - +} + + +lambda() { + + lam() { + local arg + while [[ $# -gt 0 ]]; do + arg="$1" + shift + if [[ $arg = '.' ]]; then + echo "$@" + return + else + echo "read $arg;" + fi + done + } + + eval $(lam "$@") + +} + +λ() { + lambda "$@" +} + +map() { + local x + while read x; do + echo "$x" | "$@" + done +} + +foldl() { + local f="$@" + local acc + read acc + while read elem; do + acc="$({ echo $acc; echo $elem; } | $f )" + done + echo "$acc" +} + +foldr() { + local f="$@" + local acc + read acc + + foldrr() { + local elem + read elem && acc=$(foldrr) + acc="$({ echo $acc; echo $elem; } | $f )" + echo "$acc" + } + + foldrr +} + +scanl() { + local f="$@" + local acc + read acc + echo $acc + while read elem; do + acc="$({ echo $acc; echo $elem; } | $f )" + echo "$acc" + done +} + +mul() { + ( set -f; echo $(($1 * $2)) ) +} + +add() { + echo $(($1 + $2)) +} + +sub() { + echo $(($1 - $2)) +} + +div() { + echo $(($1 / $2)) +} + +mod() { + echo $(($1 % $2)) +} + + +sum() { + foldl lambda a b . 'echo $(($a + $b))' +} + +product() { + foldl lambda a b . 'echo $(mul $a $b)' +} + +factorial() { + seq 1 $1 | product +} + +splitc() { + cat - | sed 's/./&\n/g' +} + +join() { + local delim=$1 + local pref=$2 + local suff=$3 + echo $pref$(cat - | foldl lambda a b . 'echo $a$delim$b')$suff +} + +revers() { + foldl lambda a b . 'append $b $a' +} + +revers_str() { + cat - | splitc | revers | join +} + +try() { + local f="$@" + local cmd=$(cat -) + ret="$(2>&1 $cmd)" + local status=$? + list "$cmd" $status $(list $ret | join \#) | $f +} + +ret() { + echo $1 +} + +filter() { + local x + while read x; do + ret=$(echo "$x" | "$@") + $ret && echo $x + done +} + +strip() { + local arg=$1 + cat - | map lambda l . 'ret ${l##'$arg'}' | map lambda l . 'ret ${l%%'$arg'}' +} + +buff() { + local cnt=-1 + for x in $@; do + [[ $x = '.' ]] && break + cnt=$(add $cnt 1) + done + local args='' + local i=$cnt + while read arg; do + [[ $i -eq 0 ]] && list $args | "$@" && i=$cnt && args='' + args="$args $arg" + i=$(sub $i 1) + done + [[ ! -z $args ]] && list $args | "$@" +} + +tup() { + list "$@" | join , '(' ')' +} + +tupx() { + if [[ $# -eq 1 ]]; then + local arg + read arg + tupx "$1" "$arg" + else + local n=$1 + shift + list "$@" | strip '\(' | strip '\)' | unlist | cut -d',' -f${n} + fi +} + +tupl() { + tupx 1 "$@" +} + +tupr() { + tupx 2 "$@" +} + +zip() { + local list=$* + cat - | while read x; do + y=$(list $list | take 1) + tup $x $y + list=$(list $list | drop 1) + done +} +