How to implement this foldl0 function without helper method? - functional-programming

I have following code:
function foldr0(list, func) {
if (list.length == 0) {
return 0;
} else {
return func(list[0], foldr0(list.slice(1), func));
}
}
function foldl0(list, func) {
if (list.length == 0) {
return 0;
} else {
return ?
}
}
I know it is easy to implement a recursive foldl0 with an iterative logic by defining a helper method iter(list, func, part_result) and store the result as an argument. But how to implement foldl0 without helper method just like foldr0's implementation?
NOTICE: I wrote this problem with Javascript for convenience. Please solve it with car and cdr, thanks.

We're going to look at the computational process evolved by each generic foldr and foldl. Seeing the implementations below, compare how f gets the result of foldr, but foldl gets the result of f
const foldr = ( f , acc , xs ) =>
isEmpty (xs)
? acc
: f ( foldr ( f , acc , tail ( xs ) )
, head ( xs )
)
const foldl = ( f , acc , xs ) =>
isEmpty (xs)
? acc
: foldl ( f
, f ( acc , head ( xs ) )
, tail ( xs )
)
Let's look closer at the process now – in foldr, you can see how acc (0) gets passed all the way down the call stack before any f is ever computed
// example call
foldr ( f , 0 , [ 1 , 2 , 3 ] )
// notice we can't run f yet, still waiting for foldr
f ( foldr ( f , 0 , [ 2 , 3 ] )
, 1
)
// now 2 f calls pending; still waiting on foldr
f ( f ( foldr ( f , 0 , [ 3 ] )
, 2
)
, 1
)
// now 3 f calls pending, still waiting on foldr
f ( f ( f ( foldr ( f , 0 , [] )
, 3
)
, 2
)
, 1
)
// now we can compute the inner most f, working our way out
f ( f ( f ( 0
, 3
)
, 2
)
, 1
)
// in other words, foldr traverses your input and creates a stack of f calls
f ( f ( f ( 0 , 3 ) , 2 ) , 1 )
The call stack for foldl is much different – notice how the acc is used immediately
// pretend f = ( x , y ) => x + y
foldl ( f
, 0
, [ 1 , 2 , 3 ]
)
// this time f is called first, and the result becomes the next acc
foldl ( f
, f ( 0 , 1 ) // next acc = 1
, [ 2 , 3 ]
)
// f is always computed before recurring
foldl ( f
, f ( 1 , 2 ) // next acc = 3
, [ 3 ]
)
// notice how foldl stays nice and flat (foldl uses a tail call, foldr doesn't)
foldl ( f
, f ( 3 , 3 ) // next acc = 6
, []
)
// when the input is empty, the acc is just returned
foldl ( f
, 6
, [] // empty input
)
// result
6
So why are we looking at these generics? Well the point is to show you what the computational process looks like. It's in the visualization of the process that you can see how data moves through the program.
In foldr you can see how acc is immediately passed all the way down the call stack – so you could effectively drop the acc parameter and replace acc with 0 and there is your foldr0 – which is precisely what you have
const foldr0 = ( f , xs ) =>
isEmpty (xs)
? 0
: f ( foldr0 ( f , tail ( xs ) )
, head ( xs )
)
However, that's not the case with foldl – a new acc is computed in each step and it's needed to compute the next step, so we can't just drop the parameter and replace with 0 like we did with foldr. Instead, the easiest (and smartest) implementation becomes
const foldl0 = ( f , xs ) =>
foldl ( f , 0 , xs )
const foldr0 = ( f , xs ) =>
foldr ( f , 0 , xs )
This doesn't meet your criteria of "no helper method", but that's not really a real thing. The exercise is likely meant to show you why it's challenging to implement a left fold without an auxiliary helper; as a means of helping you visualize process.
tl:dr;
JavaScript is full of all sorts of tricks though, so you can cheat to pass your class and prevent yourself from learning anything!
const isEmpty = xs =>
xs.length === 0
const head = ( [ x , ... xs ] ) =>
x
const tail = ( [ x , ... xs ] ) =>
xs
const foldl0 = ( f , xs , acc = 0 ) =>
isEmpty (xs)
? acc
: foldl0 ( f
, tail ( xs )
, f ( acc , head ( xs ) )
)
const myFunc = ( x , y ) =>
`( ${x} + ${y} )`
console.log ( foldl0 ( myFunc , [ 1 , 2 , 3 ] ) )
// ( ( ( 0 + 1 ) + 2 ) + 3 )

Just use exactly the same approach as in foldr0 but split the array to the other side:
function foldl0(list, func) {
if (list.length == 0) {
return 0;
} else {
return func(list[list.length-1], foldr0(list.slice(0, -1), func));
// ^^^^^^^^^^^^^ ^^^^^
// last without last
}
}
Of course this would be much easier if you had foldl/foldr functions with a parameter for the initial accumulator value.

A very simplistic approach by using an Haskellesque pattern matching by the rest operator could be done as follows;
var foldl0 = ([x0,x1,...xs],f) => xs.length ? foldl0([f(x0,x1)].concat(xs),f)
: f(x0,x1);
console.log(foldl0([1,2,3,4], (x,y) => x + y));

Related

presto lambda function variable inside string

I am writing a presto query
transform_values(
string_int_map,
(k, v) -> IF(
some_string LIKE '%v%',
1,
0
)
)
the 'v' inside like expression is the variable from (k, v). How can I make it happen?

Vector of Vectors created with the vec! macro contain different capacities

I have a vectormatrix_a, which contains 3 vectors, and it is initialized with the vec! macro.
Every vector should have a capacity of 3, due to Vec::with_capacity(dim), but only the last vector has a capacity of 3. The other vectors have a capacity of 0.
Can someone explain why that is?
fn main() {
let dim = 3;
let matrix_a: Vec<Vec<i32>> = vec![Vec::with_capacity(dim); dim];
for vector in matrix_a{
println!("Capacity of vector: {}", vector.capacity());
}
}
Output:
Capacity of vector: 0
Capacity of vector: 0
Capacity of vector: 3
According to the documentation, vec! is defined as:
macro_rules! vec {
( $ elem : expr ; $ n : expr ) => (
$ crate:: vec:: from_elem ( $ elem , $ n )
);
( $ ( $ x : expr ) , * ) => (
< [ _ ] > :: into_vec (
$ crate:: boxed:: Box:: new ( [ $ ( $ x ) , * ] )
)
);
( $ ( $ x : expr , ) * ) => ( vec ! [ $ ( $ x ) , * ] )
}
In your case, it means that:
vec![Vec::with_capacity(dim); dim]
is expanded into:
std::vec::from_elem(Vec::with_capacity(dim), dim)
The definition of Vec::from_elem is hidden in the documentation, but can be found in the source:
pub fn from_elem<T: Clone>(elem: T, n: usize) -> Vec<T> {
unsafe {
let mut v = Vec::with_capacity(n);
let mut ptr = v.as_mut_ptr();
// Write all elements except the last one
for i in 1..n {
ptr::write(ptr, Clone::clone(&elem));
ptr = ptr.offset(1);
v.set_len(i); // Increment the length in every step in case Clone::clone() panics
}
if n > 0 {
// We can write the last element directly without cloning needlessly
ptr::write(ptr, elem);
v.set_len(n);
}
v
}
}
And this where the heart of the mystery is solved:
the element is cloned n - 1 times, for the n - 1 first elements of the vector, and then moved into the n-th slot.
cloning a vector does not clone its capacity, only its elements.
Thus the result you get is exactly as intended, if not as expected.
As stated, this is because vec![x; y] clones the value. To avoid this, you can instead collect your vector:
let matrix_a: Vec<Vec<i32>> = (0..dim).map(|_| Vec::with_capacity(dim)).collect();
This seperately initializes each element, giving you complete allocations.

Binding atoms to the result of a recursive goal in Prolog

So let's say I'm trying to find the sum of all factors of 5 below a certain maximum number. I'm doing this recursively, because that seemed easiest. This is my code:
isFactor(X):-
Y is X mod 5,
Y = 0.
sumAll(Number, Result):-
sumAll(Number, 0, Result).
sumAll(Number, RunningTotal, Result):-
(isFactor(Number) ->
NextTotal is RunningTotal + Number;
NextTotal is RunningTotal),
NextNumber is Number - 1,
(NextNumber > 0 ->
mulSum(NextNumber, NextTotal, NextResult);
NextResult is RunningTotal),
number(NextResult) -> % this test is so that the interpreter
write(NextResult), nl; % doesn't print out a bunch of extra stuff
true. % (the internal IDs of each binding of
% NextResult maybe?) after the answer.
Now, this works (that is, it prints the correct sum), but I am slightly miffed that I can't figure out how to arrange the code so that doing
| ?- sumAll(10, X).
binds X to 10, rather than printing '10' and asserting 'yes' at the end.
My instinct is to somehow rebind Result to NextResult if NextNumber > 0 (line 13) is true, but I suspect that's just years of Python programming trying to assert themselves.
Is there a way of 'returning' the result of a goal all the way up the nested recursions here? Or am I just thinking about this all wrong?
That's awfully complicated for something simple. To sum all elements of a list that are divisible by N, all you need is this tail recursive implementation:
sum_all( Xs , N , Sum ) :-
sum_all( Xs , N , 0 , Sum )
.
sum_all( [] , _ , S , S ) .
sum_all( [X|Xs] , N , T , S ) :-
X mod N =:= 0 ,
! ,
T1 is T+X ,
sum_all(Xs,N,T1,S)
.
sum_all( [_|Xs] , N , T , S ) :-
sum_all(Xs,N,T,S)
.
The non-tail recursive implementation is a bit simpler but will blow its stack on a long list:
sum_all( [] , _ , 0 ) .
sum_all( [X|Xs] , N , S ) :-
sum(Xs,N,T) ,
( X mod N =:= 0 -> S is T+X ; S is T )
.
You could even do something like this to decompose the extraction of "interesting" values from the summing of the list:
sum_all(Xs,N,Sum) :-
findall( X , ( member(X,Xs), X mod N =:= 0 ) , L ) ,
sum(L,Sum)
.
sum(L,S) :- sum(L,0,S).
sum( [] , S ,S ) .
sum( [X|Xs] , T ,S ) :- T1 is T+X , sum(Xs,T1,S) .
Once you have that, then you can simply say:
sum_modulo_N_values( Xs , N ) :-
sum_all(Xs,N,Sum) ,
writenl( sum = Sum )
.
Invoke it something like this
sum_modulo_N_values( [1,2,5,6,7,10,11,15,31,30] , 5 ) .
And you'll get the the expected sum = 60 written to the console.
Your code seems more complex than needed, maybe such complexity hides an important fact:
in sumAll(Number, RunningTotal, Result):- Result is a singleton. Then there are little chances to get back the computed value.
I would try to get rid of number(NextResult) -> etc.. (btw you usually need parenthesis to get the expected nesting when using if/then/else - that is (C -> T ; F) ), and 'assign' instead to Result.

Case Statements and Pattern Matching

I'm coding in SML for an assignment and I've done a few practice problems and I feel like I'm missing something- I feel like I'm using too many case statements. Here's what I'm doing and the problem statements for what I'm having trouble with.:
Write a function all_except_option, which takes a string and a string list. Return NONE if the string is not in the list, else return SOME lst where lst is like the argument list except the string is not in it.
fun all_except_option(str : string, lst : string list) =
case lst of
[] => NONE
| x::xs => case same_string(x, str) of
true => SOME xs
| false => case all_except_option(str, xs) of
NONE => NONE
| SOME y=> SOME (x::y)
Write a function get_substitutions1, which takes a string list list (a list of list of strings, the substitutions) and a string s and returns a string list. The result has all the strings that are in some list in substitutions that also has s, but s itself should not be in the result.
fun get_substitutions1(lst : string list list, s : string) =
case lst of
[] => []
| x::xs => case all_except_option(s, x) of
NONE => get_substitutions1(xs, s)
| SOME y => y # get_substitutions1(xs, s)
-
same_string is a provided function,
fun same_string(s1 : string, s2 : string) = s1 = s2
First of all I would start using pattern matching in the function definition
instead of having a "top-level" case statement. Its basically boils down to the
same thing after de-sugaring. Also I would get rid of the explicit type annotations, unless strictly needed:
fun all_except_option (str, []) = NONE
| all_except_option (str, x :: xs) =
case same_string(x, str) of
true => SOME xs
| false => case all_except_option(str, xs) of
NONE => NONE
| SOME y => SOME (x::y)
fun get_substitutions1 ([], s) = []
| get_substitutions1 (x :: xs, s) =
case all_except_option(s, x) of
NONE => get_substitutions1(xs, s)
| SOME y => y # get_substitutions1(xs, s)
If speed is not of importance, then you could merge the two cases in the first function:
fun all_except_option (str, []) = NONE
| all_except_option (str, x :: xs) =
case (same_string(x, str), all_except_option(str, xs)) of
(true, _) => SOME xs
| (false, NONE) => NONE
| (false, SOME y) => SOME (x::y)
But since you are using append (#), in the second function, and since it is not
tail recursive, I don't believe that it your major concern. Keep in mind that
append is potential "evil" and you should almost always use concatenation (and
then reverse your result when returning it) and tail recursion when possible (it
always is).
If you really like the explicit type annotations, then you could do it like this:
val rec all_except_option : string * string list -> string list option =
fn (str, []) => NONE
| (str, x :: xs) =>
case (same_string(x, str), all_except_option(str, xs)) of
(true, _) => SOME xs
| (false, NONE) => NONE
| (false, SOME y) => SOME (x::y)
val rec get_substitutions1 : string list list * string -> string list =
fn ([], s) => []
| (x :: xs, s) =>
case all_except_option(s, x) of
NONE => get_substitutions1(xs, s)
| SOME y => y # get_substitutions1(xs, s)
But that is just my preferred way, if I really have to add type annotations.
By the way, why on earth do you have the same_string function? You can just do the comparison directly instead. Using an auxilary function is just wierd, unless you plan to exchange it with some special logic at some point. However your function names doesn't sugest that.
In addition to what Jesper.Reenberg mentioned, I just wanted to mention that a match on a bool for true and false can be replaced with an if-then-else. However, some people consider if-then-else uglier than a case statement
fun same_string( s1: string, s2: string ) = if String.compare( s1, s2 ) = EQUAL then true else false
fun contains( [], s: string ) = false
| contains( h::t, s: string ) = if same_string( s, h ) then true else contains( t, s )
fun all_except_option_successfully( s: string, [] ) = []
| all_except_option_successfully( s: string, h::t ) = if same_string( s, h ) then t else ( h :: all_except_option_successfully( s, t ) )
fun all_except_option( s: string, [] ) = NONE
| all_except_option( s: string, h::t ) = if same_string( s, h ) then SOME t else if contains( t, s ) then SOME ( h :: all_except_option_successfully( s, t ) ) else NONE

ocaml This expression has type 'a list but is here used with type X(account)

there is piece of ocaml which works correctly
type position = {symbol: string; holding: int; pprice : float; };;
type account = {name: string; max_ind_holding:float; pos:position list};;
let print_position pos = print_string "Holding: "; print_int pos.holding;
print_string ( " " ^ pos.symbol ^ "#" );
print_float pos.pprice;
print_newline( );;
let print_account acct = print_string ( "Account_ID " ^ acct.name );
print_newline( );
List.iter print_position acct.pos;;
(*MAIN PART OF CODE *)
let hashtbl_function db =
let hash_tbl_fold = Hashtbl.fold ( fun x y z -> ( ( y ) :: z ) ) db [] in
( fun x -> List.iter print_account x ) hash_tbl_fold (* THIS WORKS FINE *)
;;
But, if i want to change last like to do iteration of 'position list' in this function (not in print_account), i will got error :
let hashtbl_function db =
let hash_tbl_fold = Hashtbl.fold ( fun x y z -> ( ( y ) :: z ) ) db [] in
( fun x -> List.iter print_position x ) hash_tbl_fold.pos (* Why this doesn't work ???*)
;;
Error: This expression has type 'a list but is here used with type account
But hash_tbl_fold.pos is list of position, this is not account type. Right?
In print_account - acct.pos (to get 'a list) is work, but in hashtbl_function, hash_tbl_fold.pos -> not.
How it can be, that the same expression only works in one of the functions ?
How i can iterate 'position list' in hashtbl_function?
thanks in advance!
Well, I'm not sure what exactly you want to do but I can tell you why it doesn't work.
hashtbl_fold gives you a list of accounts (type account list) but then you are doing hashtbl_fold.pos; you cannot get a pos field of a list, hence the error.
In print_account, acct.pos works because acct is a single account; not a list of accounts.
What do you want to do? Print all positions of all accounts? Or just positions of a single (which?) account?
Your answer (this is not account, but account list type) help me to figure it out.
Now, i can use hash_tbl_fold.pos inside my hashtbl_function.
This works for me:
let hash_tbl_fold = Hashtbl.fold ( fun x y z -> ( ( y ) :: z ) ) db [] in
List.iter ( fun x -> List.iter print_position x.pos ) hash_tbl_fold
Tnx!

Resources