I have this type for a lazy list:
type 'a lazyList = Cons of 'a * (unit -> 'a lazyList)
I wrote a function that returns the first n elements from such a list:
let rec take n l =
if (n = 0) then []
else
match l with h :: t -> h :: take (n - 1) (t ())
So the idea is that I take this first element of the lazy list and then evaluate the list by calling () on it.
But instead I have to write it like this:
let rec take n l =
if (n = 0) then []
else
match l with Cons ((h, t)) -> h :: take (n - 1) (t ())
Why do I first have to wrap it with Cons?
Related
let rec first_part n l =
if n = 0 then
[]
else
match l with
| [] -> []
| x :: xs -> x :: first_part n-1 xs
let rec second_part n l =
match l with
| [] -> []
| x :: xs ->
if n = 0 then l
else second_part n-1 xs
let rec split n l =
match n with
| 0-> ([], l)
| n -> (first_part n l , second_part n l)
This isn't a very well posed question. You don't show the details of the error or ask a specific question. You also didn't format the code in a readable way (I improved it for you).
Your problem is that
first_part n-1 xs
is parsed like this
(first_part n) - (1 xs)
Function calls in OCaml (juxtaposed expressions) have high precedence. So you need parentheses around (n - 1) in two places.
Im new to f# and i'm trying to make this exercise:
"Implement a function"
let rec nth(n : int) (l : List<'a>) : Option<'a> =
that returns the element in position n in l. The function must handle appropriately the case where the index is invalid
this is my current code but I'm kinda stuck:
let rec nth (n : int) (l : List<'a>) : Option<'a> =
if n > l.Length then
None
else
match l with
| [] -> None
Thanks for the help!
There is a built-in function List.tryItem
let rec nth(n : int) (l : List<'a>) : Option<'a> =
l |> List.tryItem n
Can you use any functionality provided by the core library at all? If so, I suggest the following function:
let nth (n : int) (l : 'a list) : 'a option =
if n < 1 || n > l.Length then None else Some l.[n - 1]
This just checks whether the index is within permitted boundaries, then returns the element at the appropriate index. The index-item operator is zero-based, therefore we need to subtract one from the number passed into the function, and the list iteration is done by the compiler behind the scenes.
If you need to do it completely manually, I suggest the following function:
let nth (n : int) (l : 'a list) : 'a option =
let rec inner i = function
| [] -> None
| x :: _ when i = 0 -> Some x
| _ :: xs -> inner (i - 1) xs
if n < 1 then None else inner (n - 1) l
This checks the lower boundary, and if it is all right, starts to iterate the list using an inner function, and decrementing the index until it is zero so it knows it reached the right index. If the list is shorter, None is returned.
How do you write a f# recursive function that accepts a positive integer n and a list xs as input, and returns a list containing only the first n elements in xs.
let rec something n xs =
..
something 3 [1..10] = [1;2;3]
The short answer is: Don't, just use Seq.take.
A simple version would be something like:
let rec take n list =
match n with
| 0 -> []
| _ -> List.head list :: take (n - 1) (List.tail list)
A tail-recursive could look like:
let rec take n list =
let rec innertake m innerlist acc =
match m with
| 0 -> List.rev acc
| _ -> innertake (m - 1) (List.tail innerlist) ((List.head innerlist) :: acc)
innertake n list []
Note that neither of these does anything to handle the case that the input list is shorter than the requested number of items.
I'm a beginner in OCaml and algorithms.
I'm trying to get the number of 5 digits numbers with no repeating digits bigger than 12345.
Here is what I did in OCaml, I tried to make as tail recursive as possible, and I also used streams. But still, due to size, it stack overflowed:
type 'a stream = Eos | StrCons of 'a * (unit -> 'a stream)
let rec numberfrom n= StrCons (n, fun ()-> numberfrom (n+1))
let nats = numberfrom 1
let rec listify st n f=
match st with
|Eos ->f []
|StrCons (m, a) ->if n=1 then f [m] else listify (a ()) (n-1) (fun y -> f (m::y))
let rec filter (test: 'a-> bool) (s: 'a stream) : 'a stream=
match s with
|Eos -> Eos
|StrCons(q,w) -> if test q then StrCons(q, fun ()->filter test (w ()))
else filter test (w ())
let rec check_dup l=
match l with
| [] -> false
| h::t->
let x = (List.filter (fun x -> x = h) t) in
if (x == []) then
check_dup t
else
true;;
let digits2 d =
let rec dig acc d =
if d < 10 then d::acc
else dig ((d mod 10)::acc) (d/10) in
dig [] d
let size a=
let rec helper n aa=
match aa with
|Eos-> n
|StrCons (q,w) -> helper (n+1) (w())
in helper 0 a
let result1 = filter (fun x -> x<99999 && x>=12345 && (not (check_dup (digits2 x)))) nats
(* unterminating : size result1 *)
(*StackOverflow: listify result1 10000 (fun x->x) *)
I can't reproduce your reported problem. When I load up your code I see this:
# List.length (listify result1 10000 (fun x -> x));;
- : int = 10000
# List.length (listify result1 26831 (fun x -> x));;
- : int = 26831
It's possible your system is more resource constrained than mine.
Let me just say that the usual way to code a tail recursive function is to build the list up in reverse, then reverse it at the end. That might look something like this:
let listify2 st n =
let rec ilist accum st k =
match st with
| Eos -> List.rev accum
| StrCons (m, a) ->
if k = 1 then List.rev (m :: accum)
else ilist (m :: accum) (a ()) (k - 1)
in
if n = 0 then []
else ilist [] st n
You still have the problem that listify doesn't terminate if you ask for more elements than there are in the stream. It might be better to introduce a method to detect the end of the stream and return Eos at that point. For example, the filter function might accept a function that returns three possible values (the element should be filtered out, the element should not be filtered out, the stream should end).
The problem is that the size of your stream result1 is undefined.
Indeed, nats is an never-ending stream: it never returns Eos.
However, filtering a never-ending stream results in another never-ending stream
since a filtered stream only returns Eos after the underlying stream does so:
let rec filter (test: 'a-> bool) (s: 'a stream) : 'a stream=
match s with
| Eos -> Eos
| StrCons(q,w) -> if test q then StrCons(q, fun ()->filter test (w ()))
else filter test (w ())
Consequently, size result1 is stuck trying to reach the end of integers.
Note also that, in recent version of the standard library, your type stream is called Seq.node.
I'm trying to make a function which can return the specific nth element of lazylist.
Here is what I made:
datatype 'a lazyList = nullList
| cons of 'a * (unit -> 'a lazyList)
fun Nth(lazyListVal, n) = (* lazyList * int -> 'a option *)
let fun iterator (laztListVal, cur, target) =
case lazyListVal of
nullList => NONE
| cons(value, tail) => if cur = target
then SOME value
else iterator (tail(), cur+1, target)
in
iterator(lazyListVal,1,n)
end
I expected the result that as recusing proceeds, eventually the variable cur gets same as the variable target, and then the function iterator returns SOME value so it will return the final nth element.
But when I compile it and run, it only returns the very first element however I test with the lazylist objects.
Please figure what is the problem. I have no idea...
cf) I made another function which is relevant to this problem, the function that transforms lazylist into SML original list containing the first N values. Codes above:
fun firstN (lazyListVal, n) = (* lazyList * int -> 'a list *)
let fun iterator (lazyListVal, cur, last) =
case lazyListVal of
nullList => []
| cons(value, tail) => if cur = last
then []
else value::iterator(tail(),cur+1,last)
in
iterator(lazyListVal,0,n)
end
The strange thing is the function firstN is properly working.
The problem is that your iterator function does case lazyListVal of ..., but the recursive tail is called laztListVal, so for every iteration, it keeps looking at the first list. Use better variable names to avoid this kind of "invisible" bug.
For a simpler definition of nth:
datatype 'a lazyList = NullList | Cons of 'a * (unit -> 'a lazyList)
fun nth (NullList, _) = NONE
| nth (Cons (x, xs), 0) = SOME x
| nth (Cons (_, xs), n) = nth (xs (), n-1)
val nats = let fun nat n = Cons (n, fn () => nat (n+1)) in nat 0 end
val ten = nth (nats, 10)
Edit: While function pattern matching is ideal here, you could also have used a case ... of ... here. A helper function seems unnecessary, though, since you can simply use the input argument n as the iterator:
fun nth (L, n) =
case (L, n) of
(NullList, _) => NONE
| (Cons (x, xs), 0) => SOME x
| (Cons (_, xs), n) => nth (xs (), n-1)
You may however want to make the function more robust:
fun nth (L, n) =
let fun nth' (NullList, _) = NONE
| nth' (Cons (x, xs), 0) = SOME x
| nth' (Cons (_, xs), n) = nth' (xs (), n-1)
in if n < 0 then NONE else nth' (L, n) end
Here having a helper function ensures that n < 0 is only checked once.
(You could also raise Domain, since negative indices are not well-defined.)