Commits

patrickl  committed 0eb7a84

[svn r534] ok

  • Participants
  • Parent commits 5a8c42f

Comments (0)

Files changed (4)

 }
 
 
-function max {
+function maximum {
 	foldl '\acc x -> if [ -z "$acc" ] || [ "$x" -gt "$acc" ] ; then echo "$x" ; else echo "$acc" ; fi' '' "$@"
 }
 
 
-function min {
+function minimum {
 	foldl '\acc x -> if [ -z "$acc" ] || [ "$x" -lt "$acc" ] ; then echo "$x" ; else echo "$acc" ; fi' '' "$@"
 }
 
 
+function take {
+	local __n="$1"
+	shift
+
+	filter '\x -> __n=$((__n-1)) ; ((__n >= 0))' "$@"
+}
+
+function drop {
+	local __n="$1"
+	shift
+
+	filter '\x -> __n=$((__n-1)) ; ((__n < 0))' "$@"
+}
+
+
 #-- and :: [Bool] -> Bool
 function and {
-	foldl -r '\acc x -> __return "$acc" && __return "$x"' 0 "$@"
+	local __out=$(foldl -r '\acc x -> __return "$acc" && __return "$x"' 0 "$@")
+	echo "$__out"
+	return "$__out"
 }
 function and_ { and "$@" >/dev/null ; }
 
 
 #-- or :: [Bool] -> Bool
 function or {
-	foldl -r '\acc x -> __return "$acc" || __return "$x"' 1 "$@"
+	local __out=$(foldl -r '\acc x -> __return "$acc" || __return "$x"' 1 "$@")
+	echo "$__out"
+	return "$__out"
 }
 function or_ { or "$@" >/dev/null ; }
 
 }
 
 
+function __passthru {
+	local __a
+	while read -r __a ; do
+		echo "$__a"
+	done
+}
+
+
 # Places args on stdin, or else passes stdin through.
 function __args2stdin {
 	if [[ "$#" -gt 0 ]] ; then
 be (possibly) multiple lines to stdout. If a function returns a scalar value, the output will be one line to 
 stdout.
 
+The output for bash expressions manipulated by \fBbashkell\fP functions is also considered as being,
+by default, stdout. For example, if you apply 'echo' to a list using \fImap\fP, the resulting list is
+a concatenation of all the stdout output for each call to 'echo'. However, in some case we are more 
+interested in the return code of an expression rather than in it's stdout output. In order to have \fBbashkell\fP 
+higher-order functions operate on the return code of an expression instead if on it's output, use \fB-r\fP
+option of that function. In that case, the stdout output of the expression will be discarded.
+
+Here are some examples:
+
+  $ map echo $ 1 2
+  1
+  2
+
+  $ map -r echo $ 1 2
+  0
+  0
+
+  $ map eval $ /bin/true /bin/false 
+
+  $ map -r eval $ /bin/true /bin/false
+  0
+  1
+
+In a way using the return code can be viewed as evaluating the bash expression in a boolean context.
+
 
 .SH LAMBDA EXPRESSIONS
 \fBbashkell\fP has support for Haskell-style lambda expressions. These can be used with the higher-order 
   file2
   file3
 
+Note: Strictly speaking, this implementation of \fImap\fP is more like \fIfmap\fP, because
+all of the outputs are concatenated together.
+
 .SS filter EXPRESSION [$ INPUT...]
 Returns elements of \fIINPUT\fP for which \fIEXPRESSION\fP is true. Note that here it is the return code
 of \fIEXPRESSION\fP that is used to determine truth, all output is discarded.
 
 Note: \fIfoldl\fP cannot be used to build a lists, i.e. \fIACC\fP must ba a scalar value.
 
-.SS all EXPRESSION [$ INPUT...]
+.SS all[_] EXPRESSION [$ INPUT...]
+Prints 0 if \fIEXPRESSION\fP is true for each input element, prints 1 otherwise. The return code
+of \fIall\fP will also follow the same rules. If you wish to discard the output of the \fIall\fP
+function, use \fIall_\fP instead.
 
-.SS any EXPRESSION [$ INPUT...]
+  $ all '\\n -> ((n > 0))' $ 1 2
+  0
 
-.SS OPTIONS
+  $ all_ '\\n -> ((n > 0))' $ 1 0
+  $ echo $?
+  1
 
+Note: \fIall\fP evaluates \fIEXPRESSION\fP for ALL input elements. It will not stop after the first
+element for which \fIEXPRESSION\fP is false.
 
+.SS any[_] EXPRESSION [$ INPUT...]
+Prints 0 if \fIEXPRESSION\fP is true for at least 1 input element, prints 1 otherwise. The return code
+of \fIany\fP will also follow the same rules. If you wish to discard the output of the \fIany\fP
+function, use \fIany_\fP instead.
 
+  $ any '\\n -> ((n > 0))' $ 1 2
+  0
 
+  $ any_ '\\n -> ((n > 0))' $ 0 0
+  $ echo $?
+  1
 
+Note: \fIany\fP evaluates \fIEXPRESSION\fP for ALL input elements. It will not stop after the first
+element for which \fIEXPRESSION\fP is true.
 
-.I COMMAND
-as an argument can also accept 
-.I lambda expressions
-instead. 
-.I Lambda expressions
-are written as in Haskell, i.e. using the following notation:
+.SS define NAME = LAMBDA_EXPRESSION
+.SS define NAME [ARG...] = BASH_EXPRESSION
 
-  \\arg1 ... argn -> COMMAND
 
-For example, instead of the command
-.I dirname
-, one could use the following lambda expression:
+.SH OTHER FUNCTIONS
+.SS and[_] [$ INPUT...]
+.SS or[_] [$ INPUT...]
+.SS take [$ INPUT...]
+.SS drop [$ INPUT...]
+.SS sum [$ INPUT...]
+.SS product [$ INPUT...]
+.SS max [$ INPUT...]
+.SS min [$ INPUT...]
 
-  \\f -> dirname $f
+.SS show INPUT... 
 
-.SH FUNCTIONS
-.SS map 
-blablabla
-.SS filter
-.SS foldl/foldr
 
 .SH AUTHOR
 Written by Patrick LeBoutillier <patl@cpan.org>.

File t/04_prelude.sh

 	"sum"
 is "`product $ 1 2 3 4 5`" 120 \
 	"product"
-is "`min $ 1 2 3 4 5`" 1 \
+is "`minimum $ 1 2 3 4 5`" 1 \
 	"min"
-is "`max $ 1 2 3 4 5`" 5 \
+is "`maximum $ 1 2 3 4 5`" 5 \
 	"max"
 
 and_ $ 0 0 0 
 			TEST_DATA="$TEST_DATA$line"
 		fi
 	else
+		if [ -n "$IN_TEST_CODE" ] ; then
+			echo "}"
+			IN_TEST_CODE=
+			IN_TEST_DATA=1
+		fi
 		if [ -n "$IN_TEST_DATA" ] ; then
 			TEST_DATA="$TEST_DATA"
-			echo 'is "`mantest`" ' '"`echo -e "'$TEST_DATA'"`"' '"man test #'$NB_TESTS'"'
+			echo 'is "x`mantest`" ' '"x`echo -e "'$TEST_DATA'"`"' '"man test #'$NB_TESTS'"'
 		fi
 		IN_TEST_CODE=
 		IN_TEST_DATA=