Functional: construct a list of integers 1..n - functional-programming

This is not homework. I'm learning Standard ML on my own. I know a bit of Scheme, too, so this question ought to be answerable in either language.
My self-imposed assignment is to write a function that constructs a list of integers from 1 to n. For example, list(7) should return [1,2,3,4,5,6,7]. An O(n) solution would be ideal.
It's easy to construct a list in reverse (i.e., [n,n-1,..,1]) in linear time:
fun list 1 = 1::nil
| list n = n::list(n-1);
My attempt to construct a list going forward is O(n^2) because the append operation is linear.
fun list 1 = 1::nil
| list n = list(n-1) # n::nil;
My next attempt was to build a list from the end to the front (right to left) by starting with the nil, attaching n to the front, and recursing backwards to 1. But it didn't work at all.
fun list n = (if n = 1
then 1
else list(n-1) :: n) :: nil;
Something makes me think I need a helper function that builds un-terminated lists to be used in the recursion, but I'm stumped.

Using the Basis Library,
fun list n = List.tabulate (n, fn x => x + 1)
With a simple accumulator,
val list =
let fun list' k 0 = k
| list' k n = list' (n::k) (n-1)
in list' nil end
This builds a list starting from the tail end. If you think of the reductions,
list 5
=> list' nil 5
=> list' (5::nil) 4
=> list' (4::5::nil) 3
=> list' (3::4::5::nil) 2
=> list' (2::3::4::5::nil) 1
=> list' (1::2::3::4::5::nil) 0
=> [1, 2, 3, 4, 5]
Alternatively,
Something makes me think I need a helper function that builds un-terminated lists to be used in the recursion, but I'm stumped.
A representation of an unterminated list is a function which takes a list and returns a list: for example, to represent 10::_, you could use fn x => 10::x.
fun list n =
let fun list' m k = if m > n then k nil else
list' (m+1) (fn x => k (m::x))
in list' 1 (fn x => x) end
Once again, if you think of the reductions,
list 5
=> list' 1 (fn x => x)
=> list' 2 (fn x => (fn x => x) (1::x))
=> list' 3 (fn x => (fn x => (fn x => x) (1::x)) (2::x))
=> list' 4 (fn x => (fn x => (fn x => (fn x => x) (1::x)) (2::x)) (3::x))
=> list' 5 (fn x => (fn x => (fn x => (fn x => (fn x => x) (1::x)) (2::x)) (3::x)) (4::x))
=> list' 6 (fn x => (fn x => (fn x => (fn x => (fn x => (fn x => x) (1::x)) (2::x)) (3::x)) (4::x)) (5::x))
=> (fn x => (fn x => (fn x => (fn x => (fn x => (fn x => x) (1::x)) (2::x)) (3::x)) (4::x)) (5::x)) nil
=> (fn x => (fn x => (fn x => (fn x => (fn x => x) (1::x)) (2::x)) (3::x)) (4::x)) (5::nil)
=> (fn x => (fn x => (fn x => (fn x => x) (1::x)) (2::x)) (3::x)) (4::5::nil)
=> (fn x => (fn x => (fn x => x) (1::x)) (2::x)) (3::4::5::nil)
=> (fn x => (fn x => x) (1::x)) (2::3::4::5::nil)
=> (fn x => x) (1::2::3::4::5::nil)
=> [1, 2, 3, 4, 5]
In this case, the algorithm can be structured such that an ordinary data structure suffices for the accumulator, but using a continuation as an accumulator is a very powerful and useful technique that should not be overlooked.

One classic approach is to build it in reverse order, then reverse it. That's two times O(n), which is of course just as O(n).

Here's a solution:
fun list n =
let
fun f 1 m = m::nil
| f n m = m::f (n-1) (m+1)
in
f n 1
end;

Here's a version using a helper function and a tail-recursion-enabling accumulator:
fun list n =
let
fun aux i acc =
if i > 0
then aux (i-1) (i::acc)
else acc
in
aux n nil
end;

With list problems like these, it is often easier to solve a more general problem.
How do I build a list containing the integers i such that n <= i <= m, in order?
The solution has a base case and an induction step:
If n > m, the list is empty.
If n <= m, the solution is to write n followed by the solution to the problem n+1 <= i <= m.
This view leads quickly to clear, concise ML code (tested):
fun range n m = if n > m then [] else n :: range (n+1) m
fun list n = range 1 n

(define (iota n)
(let f ((i n)(a '())
(if (zero? i)
(reverse a)
(f (- i 1) (cons i a)))))

Related

Why is this code is generating an infinite recursion in SML if it has a base case?

I wrote the following code in SML with the NJ Compiler:
fun all_answers (f, xs) =
let
fun aux(accu, xs_left) =
case xs of
[] => SOME accu
| x::xs' => case f(x) of
NONE => NONE
| SOME y => aux(accu#y, xs')
in
aux([], xs)
end
It works well for this tests:
val testAll1 = all_answers ((fn x => if x = 1 then SOME [x] else NONE), []) = SOME []
val testAll2 = all_answers ((fn x => if x = 1 then SOME [x] else NONE), [2,3,4,5,6,7]) = NONE
However, something weird happens with this test:
val testAll3 = all_answers ((fn x => if x = 1 then SOME [x] else NONE), [1]) = SOME [1]
After running the program, the terminal goes on forever.
I defined the tail recursion and used the pattern-match with xs' to reach the tail.
Moreover, I defined the base case to end the recursion so that if xs is [] then the auxiliary function returns SOME accumulator
Can anybody help me?
Thanks in advance.
As #kopecs pointed out, this is caused by case xs of when you want case xs_left of.
Here is a cleaned up (whitespace, naming) version of your function:
fun all_answers (f, ys) =
let
fun aux (accu, xs) =
case xs of
[] => SOME accu
| x::xs' => case f x of
NONE => NONE
| SOME y => aux (accu#y, xs)
in
aux ([], ys)
end
There are at least two things you could do to simplify the way this function is made. (1) Perform the case xs of inside the function pattern rather than in a nested case-of. (2) Remove the inner aux function and simply do the recursion in the outer function, at the expense of some tail-recursion
The first simplification might look like:
fun all_answers2 (f, ys) =
let
fun aux (accu, []) = SOME accu
| aux (accu, x::xs) =
case f x of
NONE => NONE
| SOME y => aux (accu#y, xs)
in
aux ([], ys)
end
And the second might look like:
fun all_answers' (f, []) = SOME []
| all_answers' (f, x::xs) =
case f x of
NONE => NONE
| SOME ys => case all_answers' (f, xs) of
NONE => NONE
| SOME result => SOME (ys # result)
This shows a pattern: Whenever you have
case f x of
NONE => NONE
| SOME y => case g y of
NONE => NONE
| SOME z => ...
then you have a programming pattern that could be abstracted out with a function.
There is already a standard library function that is made for this called Option.map, so you could write:
fun all_answers3 (f, ys) =
let
fun aux (accu, []) = SOME accu
| aux (accu, x::xs) =
Option.map (fn y => aux (accu#y, xs))
(f x)
in
aux ([], ys)
end
Try and play around with this function in the REPL:
- Option.map (fn y => y + 2) NONE;
> val it = NONE : int option
- Option.map (fn y => y + 2) (SOME 2);
> val it = SOME 4 : int option
Taking this in another direction, rather than an inner function:
(* Alternative to Option.map: *)
fun for NONE _ = NONE
| for (SOME x) f = f x
(* Equivalent to Option.mapPartial with "flipped" arguments: *)
fun for opt f = Option.mapPartial f opt
fun all_answers'' (f, []) = SOME []
| all_answers'' (f, x::xs) =
for (f x) (fn ys =>
for (all_answers'' (f, xs)) (fn result =>
SOME (ys # result)))
This style is more Haskell-like because it follows a monadic design pattern.

Is the Y Combinator a left fold or a right fold?

The Y combinator (from the wikipedia article) is defined as:
Y = \f.(\x.f(x x)) (\x.f(x x))
so when we call Y on g:
Y g = (\f.(\x.f(x x)) (\x.f(x x))) g
= (\x.g(x x)) (\x.g(x x))
= g((\x.g(x x)) (\x.g(x x)))
= g (Y g)
The repetition results in this:
Y g = g(Y g) = g(g(Y g)) = g(...g(Y g)...)
Because this expansion is over a unary function, I can't tell if this is a left fold or a right fold.
My understanding of a left fold is that it resembles this (with a binary function f):
f (f (f (f 1 2) 3) 4) 5)
Whereas a right fold over binary function f looks like this:
f 1 (f 2 (f 3 (f 4 5)))
I would imagine that any unary function, however, would look the same as a left-fold or right-fold expansion:
f (f (f (f (f x))))
Is this correct? If not, does the Y combinator expand into a left-fold or a right-fold?
Fixed point combinators like Y merely enable anonymous recursion. What you do with this recursion is totally up to you. You can define both a left associative fold and a right associative fold with it. I hope you don't mind me illustrating this in Javascript:
// simplified Y combinator with eta abstraction due to eager evaluation
const fix = f => x => f(fix(f)) (x);
// left fold
const foldl = fix(rec => f => acc => ([x, ...xs]) =>
x === undefined
? acc
: rec(f) (f(acc) (x)) (xs));
// right fold
const foldr = fix(rec => f => acc => ([x, ...xs]) =>
x === undefined
? acc
: f(x) (rec(f) (acc) (xs)));
console.log(
foldl(x => y => x - y) (0) ([1,2,3])); // -6
console.log(
foldr(x => y => x - y) (0) ([1,2,3])); // 2

Clojure, comparing vectors of integers: why "longer" vector is always "greater"? Is there a remedy?

It works like this:
pcc.core=> (compare [4] [2 2])
-1
pcc.core=> (compare [4 0] [2 2])
1
I want a vector comparator with "string semantics":
pcc.core=> (compare-like-strings [4] [2 2])
1 ;; or 2, for that matter
pcc.core=> (compare-like-strings [4 0] [2 2])
1
Is there a lightweigt, nice way to get what I want?
How about:
(defn compare-like-strings [[x & xs] [y & ys]]
(let [c (compare x y)]
(if (and (zero? c) (or xs ys))
(recur xs ys)
c)))
So far it's
(defn cmpv-int
"Compare vectors of integers using 'string semantics'"
[vx vy]
(let [res (first (drop-while zero? (map compare vx vy)))
diffenence (- (count vx) (count vy))]
(if res res diffenence)
)
)
based on Fabian approach.
Why not use subvec?
(defn compare-like-strings
[vec1 vec2]
(let [len (min (count vec1) (count vec2))]
(compare (subvec vec1 0 len)
(subvec vec2 0 len))))
Comparison seems to work if both vectors are the same length, so let me offer this:
(defn compare-vectors
[a b]
(compare
(reduce conj a (map #{} b))
(reduce conj b (map #{} a))))
This is basically padding the inputs with as many nils as necessary before running the comparison. I like how it looks (and it should fit your requirements perfectly) but I'm not particularly sure I'd recommend it to anyone. ;)
(compare-vectors [2 2] [2 2]) ;; => 0
(compare-vectors [4 2] [2 2]) ;; => 1
(compare-vectors [2 2] [4 2]) ;; => -1
(compare-vectors [4] [2 2]) ;; => 1
EDIT: I probably wouldn't - it's terribly inefficient.
As I said in the comments on Diego's answer, I think the least creative approach is best here: just write a loop, enumerate all the cases, and slog through it. As a bonus, this approach also works for arbitrary sequences, possibly lazy, because we don't need to rely on any vector-specific tricks.
(defn lexicographic-compare
([xs ys]
(lexicographic-compare compare xs ys))
([compare xs ys]
(loop [xs (seq xs) ys (seq ys)]
(if xs
(if ys
(let [c (compare (first xs) (first ys))]
(if (not (zero? c))
c
(recur (next xs), (next ys))))
1)
(if ys
-1
0)))))
Maybe like this?
(defn compare-like-strings [a b]
(let [res (first (drop-while zero? (map compare a b)))]
(if (nil? res)
0
res)))
The idea would be to do a pairwise comparison, returning a seq of -1, 0, or 1s and then drop all leading 0s. The first non-zero element is the first element that differs.

How to get an induction principle for nested fix

I am working with a function that searches through a range of values.
Require Import List.
(* Implementation of ListTest omitted. *)
Definition ListTest (l : list nat) := false.
Definition SearchCountList n :=
(fix f i l := match i with
| 0 => ListTest (rev l)
| S i1 =>
(fix g j l1 := match j with
| 0 => false
| S j1 =>
if f i1 (j :: l1)
then true
else g j1 l1
end) (n + n) (i :: l)
end) n nil
.
I want to be able to reason about this function.
However, I can't seem to get coq's built-in induction principle facilities to work.
Functional Scheme SearchCountList := Induction for SearchCountList Sort Prop.
Error: GRec not handled
It looks like coq is set up for handling mutual recursion, not nested recursion. In this case, I have essentially 2 nested for loops.
However, translating to mutual recursion isn't so easy either:
Definition SearchCountList_Loop :=
fix outer n i l {struct i} :=
match i with
| 0 => ListTest (rev l)
| S i1 => inner n i1 (n + n) (i :: l)
end
with inner n i j l {struct j} :=
match j with
| 0 => false
| S j1 =>
if outer n i (j :: l)
then true
else inner n i j1 l
end
for outer
.
but that yields the error
Recursive call to inner has principal argument equal to
"n + n" instead of "i1".
So, it looks like I would need to use measure to get it to accept the definition directly. It is confused that I reset j sometimes. But, in a nested set up, that makes sense, since i has decreased, and i is the outer loop.
So, is there a standard way of handling nested recursion, as opposed to mutual recursion? Are there easier ways to reason about the cases, not involving making separate induction theorems? Since I haven't found a way to generate it automatically, I guess I'm stuck with writing the induction principle directly.
There's a trick for avoiding mutual recursion in this case: you can compute f i1 inside f and pass the result to g.
Fixpoint g (f_n_i1 : list nat -> bool) (j : nat) (l1 : list nat) : bool :=
match j with
| 0 => false
| S j1 => if f_n_i1 (j :: l1) then true else g f_n_i1 j1 l1
end.
Fixpoint f (n i : nat) (l : list nat) : bool :=
match i with
| 0 => ListTest (rev l)
| S i1 => g (f n i1) (n + n) (i :: l)
end.
Definition SearchCountList (n : nat) : bool := f n n nil.
Are you sure simple induction wouldn't have been enough in the original code? What about well founded induction?

Why does (= (vector nil) (vec nil)) return false?

Is this just a quirk, or is there some fundamental concept that implies this?
vec converts into a vector(nil becomes an empty vector) while vector creates a vector with the given elements.
(vec nil) => []
(vector nil) =>
[nil]
you could have entered these expressions into a repl to see their results and why they're not equal.
user> (vec nil) ; => []
user> (vector nil) ; => [nil]
user> (= *1 *2) ; => false
Why should these be equal?

Resources