I have to code a function that receives a sequence (finite or infinite) and returns an identical sequence with the only difference that if an exception occurs during the sequence then the function returns the sequence to its beginning.
In other words, the function must return a cyclic sequence which repeated itself when it comes to an end.
I have to catch the exception with handle.
The following example must work.
listToSeq [1,2];
val it = Cons (1,fn) : int seq
restartOnError it;
val it = Cons (1,fn) : int seq
tail it;
val it = Cons (2,fn) : int seq
tail it;
val it = Cons (1,fn) : int seq
tail it;
val it = Cons (2,fn) : int seq
Can someone help me ?
Simple. You have a load of Cons(int, ->Cons(int, ...)) things (it looks like), and you want to recurse down. Watch and learn, and think it through. When you call the fn which makes the next elt in the list, you don't want to call it straight, but to handle each time, and go back to the start if you have to. So, you write that fn first. Then, you want a chap that will will tranform any elt into the one in the new list, with the tweaked next fun that sends you back to start. So, you write that guy next (third line below). Finally, just return the answer. Simple, code should be easy to follow (pseudo-code; won't quite compile and may have haskelisms).
fun cycle l =
let fun handleNext next = ((next()) handle whatever => l);
fun next (Cons(n, fn)) = Cons(n, fun ()=>next(handleNext fn))
in next l end;
Related
For my assignment, I have to take a list of tuples of people at a wedding who can't sit next to each other. Then compare it with a list of people at a table. If any two people in the same tuple are in the table list, then it should be false. Otherwise true. This is my first time coding in F# so the syntax is killing me here.
let isValidTable (cantSit:(string*string) list) (people: string list) =
let truth = true;
let rec matchPeople cantSit person1 person2=
match cantSit with
| [] -> None
| head :: tail ->
let (person1,person2) = head
if ((List.exists(fun names -> names = person1) people) && (List.exists(fun names2 -> names2 = person2) people)) then
let result2 = false
else
matchPeople tail fst snd;;
let result = true;;
matchPeople cantSit fst snd;;
let x = [("Eric", "Mark"); ("Anna", "Maya"); ("Beth", "Hope")];;
let weddingList = ["Eric"; "Anna"; "Beth"]
let validOrNah = isValidTable x weddingList;;
printf("\n%O") validOrNah;;
The problem for me is that I keep getting errors like "matchPeople constructor not defined", or "let is unfinished". Any help would be appreciated thank you!
Before: I had
if(first person is in list and second person is in list)
then Some false
else recursive statement;
This code compiled without errors but only printed null. I know variables are immutable in F#, which is making this tough.
There are many problems in your code, all caused by your unfamiliarity with F#. I'll go through it line by line and try to explain what you haven't yet understood.
let isValidTable (cantSit:(string*string) list) (people: string list) =
This is fine.
let truth = true;
There's no need for this assignment at all, since you never use the name truth anywhere else in your code. And if you did need to use it, you could just replace it with the constant true and it would read better. Let's remove this line entirely.
BTW, there's no need for semicolons at the end of lines in F#, unlike in C-like languages. The double semicolon is only used in the F# Interactive interpreter, to tell the interpreter "I'm done entering this expression". This allows you to split an expression across multiple lines, without the interpreter needing to guess when you're done (because many partial expressions in F# can look complete, so explicit expression termination is needed). I won't mention this every time a semicolon comes up, but you can remove all semicolons (and double semicolons) at the end of your lines. The only place a semicolon is needed in F# is between items in a list, such as in x or in weddingList.
On to the next line.
let rec matchPeople cantSit person1 person2=
This looks fine, but in fact, you don't need the person1 and person2 parameters at all. My guess is that you have them in the parameter list because you think you need to declare variables before you create them, but that's not how F# works at all. When you write let (person1, person2) = head later in the function, the variables person1 and person2 are created right there, and there's no need to have them as function parameters. So you can remove them, and your function definition will become let rec matchPeople cantSit =
match cantSit with
This is fine.
| [] -> None
This is a minor mistake. Elsewhere you look like you want to return a Boolean value, but here you return an option instead. In F#, all branches of match and/or if...else must return the same type. Your isValidTable function clearly is intended to return a Boolean, and so is matchPeople, so this should be a Boolean value as well. The question is, should this line return false or true? To answer that question, think about what an empty cantSit list means in the semantics of your problem domain. It would mean that there is nobody who can't sit with each other, so the seating list is valid no matter who's at the table. Or, of course, it could also mean that you've reached the end of the cantSit list by multiple recursive calls, in which case the value you return here will be the value you return finally from the last recursive call. And again, returning true is what you want, because if you had found an invalid sitting pair earlier, you would have returned false immediately and not made another recursive call. So if you get to the point where the cantSit list is empty, then you're ready to return true.
| head :: tail ->
This is fine.
let (person1,person2) = head
This is not just fine, it's quite good.
if ((List.exists(fun names -> names = person1) people) && (List.exists(fun names2 -> names2 = person2) people)) then
This is fine, but could be simplified. There's a List.contains function that does what you want here. Any call of the type List.exists (fun item -> item = value) itemList) can be simplified to List.contains item itemList. So this would become if (List.contains person1 people) && (List.contains person2 people) then, which is much easier to read and understand quickly.
let result2 = false
This is incorrect; a let assignment in F# has no value, and since it's the last expression in the if block, that means the if block would not have a value if its condition turns out to be true. This is why you're getting the "unfinished" errors: in F#, a let assignment may never be the last expression of a code block. It must always be followed by an expression that has a value. What you're actually trying to do here is pretty clear: you want to return false if both people are in the list. You can do that by just writing false in this line; I'll explain a little more here.
In F#, if...else is an expression that returns a value, not a statement like it is in most other languages. So you can write something like this:
let n = 5
let s = if n % 2 = 0 then "Even" else "Odd"
printfn "%s" s // Prints "Odd"
Here, your if...else is the last line of one case of the match expression, so its value will be the value of the match expression. And the match expression is the last expression of the matchPeople function, so its value will be the return value of the function. So in the case where you find a matching pair that can't sit together (the true branch of this if...else expression), then you just have to have a line saying false, and that will be the return value of the function if it hits that branch.
Moving on to your next line.
else
This is fine, obviously.
matchPeople tail fst snd;;
This is fine once you remove the fst and snd (since we changed our function signature so that matchPeople now takes just one argument), and remove the semicolons as mentioned previously.
let result = true;;
Same comment as for the earlier let result2 = false line: a let assignment may never be the last line of a code block in F#. Here, what you want to do is let the result of the recursive matchPeople call be the final result of your "outer" level of recursion. You can do that by simply deleting this let result = true line, so that the matchPeople call is the last line of the else block. That means that its result will be the result of the else block, and since the if...else expression is the last expression of this case of match, the recursive call will be the last expression of the match statement. And since the match statement is the last expression of the matchPeople function, its result will also be the result of the overall function (if the code reaches the else branch). That means that this recursive call is in tail position, which is an important concept later: a call is in tail position if its result will be the result of the overall function. A call in tail position is usually known as a "tail call" for short. I won't go into depth about tail calls here, except to say that a tail call can be optimized by the compiler so that it will never cause a stack overflow error, no matter how many times you go through the recursive call. For now, we'll put tail calls aside and go on to look at the rest of your code:
matchPeople cantSit fst snd;;
As with the other call, just remove the fst and snd parameters (and the double semicolon) and this will be fine.
let x = [("Eric", "Mark"); ("Anna", "Maya"); ("Beth", "Hope")];;
let weddingList = ["Eric"; "Anna"; "Beth"]
let validOrNah = isValidTable x weddingList;;
printf("\n%O") validOrNah;;
All of this is fine once you remove the unnecessary double semicolons. I'd probably write printfn "%O" validOrNah on the last line, but that's personal preference: I like to print a newline at the end of my output, rather than the beginning (printfn prints a newline after whatever you ask it to print, while printf without a trailing n in the function name does not print a trailing newline). But what you have written here is fine.
Making all those changes, here's what your code turns into:
let isValidTable (cantSit:(string*string) list) (people: string list) =
let rec matchPeople cantSit =
match cantSit with
| [] -> true
| head :: tail ->
let (person1,person2) = head
if (List.contains person1 people) && (List.contains person2 people) then
false
else
matchPeople tail
matchPeople cantSit
let x = [("Eric", "Mark"); ("Anna", "Maya"); ("Beth", "Hope")]
let weddingList = ["Eric"; "Anna"; "Beth"]
let validOrNah = isValidTable x weddingList
printfn "%O" validOrNah
I made no changes to your logic since it's correct (well done!), so once you make these syntax fixes that I suggested, this should run and print the correct results.
I am just trying to figure out how immutable things like a List are working, and how I can add things to it?
I am very sorry for asking such dumb questions, but why is here my list always empty when printing it out?
var end = false
val list = List()
while (!end) {
val input = scala.io.StdIn.readLine("input:")
if (input == "stop" ) end = true
else input :: list
}
println(list)
}
Sorry for my inconvenience and this rather stupid question!
I am just trying to figure out how immutable things like a List are working, and how I can add things to it?
You can't. That's what immutable means, after all. If Latin is not your cup of tea, the English translation of immutable is unchangeable. It should be clear now, why you can't change something that is unchangeable.
I am very sorry for asking such dumb questions, but why is here my list always empty when printing it out?
You create an empty list, and you never change it (because it cannot be changed anyway). So, of course it is empty.
What can you can do, however, is create a new list which is almost exactly like the old list, except with a new item prepended to the front. That's what you are doing here:
input :: list
However, you don't assign this new list anywhere, you don't return it, you completely ignore it.
If you want to actually use your list in any way, you need to remember it somehow. The most obvious solution would be to assign it to a variable:
var end = false
var list: List[String] = List() // note: `var` instead of `val`
while (!end) {
val input = scala.io.StdIn.readLine("input:")
if (input == "stop" ) end = true
else list = input :: list // note: assign to `list`
}
println(list)
However, that's not very idiomatic. After all, we have now taken an immutable list and assigned it to a mutable variable … IOW, we have just moved the mutability around.
Instead, we could use a recursive solution:
def buildListFromInput(list: List[String] = List()): List[String] = {
val input = scala.io.StdIn.readLine("input:")
if (input == "stop") list else buildListFromInput(input :: list)
}
println(buildListFromInput())
This solution is not only recursive, the recursive call is also in tail position (IOW, the method is tail-recursive), which means that it will be just as efficient as a while loop (in fact, it will be compiled into a while loop, or more precisely, into a GOTO). The Scala Language Specification guarantees that all implementations of Scala must eliminate direct tail-recursion.
The reason
println(list)
is only printing out an empty list is because the bit
input :: list
isn't actually mutating the list itself. It is simply, in this case, very temporarily, creating a list containing the input at the front.
Try
println(input :: list)
or
val newList = input :: list
println(newList)
and you'll see what I mean.
Try rewriting the code in more functional way. Every operation on Immutable data structures return new instance with change. So :: operator creates new List with input on front. You might want to try rewrite this code as tail recursive function as follows.
#tailrec
def scanInput(continue: Boolean,acc: List[String]): List[String] = {
val input = scala.io.StdIn.readLine("input:")
if(!continue) acc
else scanInput(input != "stop", input :: acc)
}
Above code has no mutating state and it suits more Scala functional style.
In scala List is immutable.
Then how can I add items to the list?
When you add an item to list a new List instance is crated with a item as its head and its tail now contains the previous list.
If you have list of "1,2,3" called intList internally it is represented as
List(3, List(2, List(1, Nil) ) )
If you add an element 4 to this intList
List(4, intList )
Lets call this newList
Note intList still contains List(3, List(2, List(1, Nil) ) ).
If you want the intList to refer the newList You will have to do
intList = intList.add(4)
How can I fix my code
Change list from val to var. Then you can assign resulting List to list variable
list = input :: list
Source: Online course on Scala called Functional Programming Principles in Scala
Thank you for all your help, I appreciate your help so much from all of you!
I should have taken a closer look at recursion since it seems to be really important like in Scala!
But trough your help I am getting an better idea of how it works!
I just tried to figure out how your solutions are working and created my own:
val list = List()
def scanInput(acc: List[String]): List[String] = {
val input = scala.io.StdIn.readLine("input:")
input match {
case "stop" => acc
case _ => scanInput(input :: acc)
}
}
println(scanInput(list))
I have a problem with writing a function which result is as shown below:
split([7;1;4;3;6;8;2], 4) = ([1;3;2;4], [7;6;8])
my current code i managed to write:
let split(list, number)=
let split1(list, number, lesser, greater)=
if list = [] then lesser::greater
else if List.hd list <= element then (List.hd list)::(lesser)
else (List.hd list)::(greater)
in
(List.tl lista, element, [], []);;
Thanks in advance for your help.
For the future, it helps to be more specific when asking a question on SO. What exactly is your problem? SO users will be skeptical of someone who wants others to help them, but won't help themselves.
Your code has nearly the correct structure, but there are a few errors in there that seem to be getting in your way.
Firstly lesser::greater is wrong, since the left hand side of a cons operator must be a list itself, but what you really want is a list where both of these are elements. So instead try [lesser;greater].
Secondly, if you think through your code, you will notice that it suddenly stops. You checked the first element, but you didn't look at the rest of the list. Since you want to keep splitting the list, you need your code to keep executing till the end of the list. To achieve this, we use recursion. Recursion mean that your function split1 will call itself again. It can be very confusing the first time you see it - each time split1 runs it will take the first element off, and then split the remainder of the list.
What does (List.hd list)::(lesser) actually mean? The lesser here really means all of the lesser elements in the rest of the list. You need to keep taking an element out of the list and putting it in either lesser or greater.
Finally avoid using List.hd excessively - it is neater to find the head and tail using pattern matching.
Here's a working version of the code:
let split(list, number)=
let rec split1(list, number, lesser, greater)=
match list with
| [] -> [List.rev lesser;List.rev greater]
| head::tail ->
match (head <= number) with
true -> split1(tail,number,head::lesser,greater)
| false -> split1(tail,number,lesser,head::greater)
in split1(list, number, [], []);;
split([1;2;3;4;5],3);;
The split1 function takes the elements off one at a time, and adds them to the lists.
Maybe my comments on the following code snippet would help:
let split list num =
let rec loop lesser greater list =
match list with
| [] -> (lesser, greater)
(* when your initial list is empty, you have to return the accumulators *)
| x :: xs ->
if x <= num then
(* x is lesser than num, so add x in the lesser list and
call loop on the tail of the list (xs) *)
else
(* x is greater than num, so add x in the greater list and
call loop on the tail of the list (xs) *)
in
(* here you make the first call to loop by initializing
your accumulators with empty list*)
loop [] [] list
I want to make a program insertAt where z is the place in the list, and y is the number being inserted into the list xs. Im new to haskell and this is what I have so far.
insertAt :: Int-> Int-> [Int]-> [Int]
insertAt z y xs
| z==1 = y:xs
but I'm not sure where to go from there.
I have an elementAt function, where
elementAt v xs
| v==1 = head xs
| otherwise = elementAt (v-1) (tail xs)
but I'm not sure how I can fit it in or if I even need to. If possible, I'd like to avoid append.
If this isn't homework: let (ys,zs) = splitAt n xs in ys ++ [new_element] ++ zs
For the rest of this post I'm going to assume you're doing this problem as homework or to teach yourself how to do this kind of thing.
The key to this kind of problem is to break it down into its natural cases. You're processing two pieces of data: the list you're inserting into, and the position in that list. In this case, each piece of data has two natural cases: the list you're procssing can be empty or not, and the number you're processing can be zero or not. So the first step is to write out all four cases:
insertAt 0 val [] = ...
insertAt 0 val (x:xs) = ...
insertAt n val [] = ...
insertAt n val (x:xs) = ...
Now, for each of these four cases, you need to think about what the answer should be given that you're in that case.
For the first two cases, the answer is easy: if you want to insert into the front of a list, just stick the value you're interested in at the beginning, whether the list is empty or not.
The third case demonstrates that there's actually an ambiguity in the question: what happens if you're asked to insert into, say, the third position of a list that's empty? Sounds like an error to me, but you'll have to answer what you want to do in that case for yourself.
The fourth case is most interesting: Suppose you want to insert a value into not-the-first position of a list that's not empty. In this case, remember that you can use recursion to solve smaller instances of your problem. In this case, you can use recursion to solve, for instance, insertAt (n-1) val xs -- that is, the result of inserting your same value into the tail of your input list at the n-1th position. For example, if you were trying to insert 5 into position 3 (the fourth position) of the list [100,200,300], you can use recursion to insert 5 into position 2 (the third position) of the list [200,300], which means the recursive call would produce [200,300,5].
We can just assume that the recursive call will work; our only job now is to convert the answer to that smaller problem into the answer to the original problem we were given. The answer we want in the example is [100,200,300,5] (the result of inserting 5 into position 4 of the list [100,200,300], and what we have is the list [200,300,5]. So how can we get the result we want? Just add back on the first element! (Think about why this is true.)
With that case finished, we've covered all the possible cases for combinations of lists and positions to update. Since our function will work correctly for all possibilities, and our possibilities cover all possible inputs, that means our function will always work correctly. So we're done!
I'll leave it to you to translate these ideas into Haskell since the point of the exercise is for you to learn it, but hopefully that lets you know how to solve the problem.
You could split the list at index z and then concatenate the first part of the list with the element (using ++ [y]) and then with the second part of the list. However, this would create a new list as data is immutable by default. The first element of the list by convention has the index 0 (so adjust z accordingly if you want the meaning of fist elemnt is indexed by 1).
insertAt :: Int -> Int-> [Int] -> [Int]
insertAt z y xs = as ++ (y:bs)
where (as,bs) = splitAt z xs
While above answers are correct, I think this is more concise:
insertAt :: Int -> Int-> [Int]-> [Int]
insertAt z y xs = (take z xs) ++ y:(drop z xs)
I am having two lists in SML, lets say list A [(a,b,c),(d,e,f)] and list B [b,e]. I want to count how many occurrence of each item in B that matches the second element of each triple in A. The output should be 2. Because b and e each occurs once in A.
This is my code so far but my counter is always set to 0 when I move from one element to another in B. I know in Java this will just be a simple double for loop.
fun number_in_months (d : (int * int * int ) list, m : (int) list) =
if null m then 0
else if null d then number_in_months(d, tl m)
else if (#2(hd d)) = (hd m) then 1 + number_in_months (tl d, m)
else number_in_months(tl d, m)
The code is not accumulating a value between recursive calls. There may be other logic errors too.
Accumulating a value using recursion and functions is a common pattern which you can read more about here. It's essence is to deconstruct a list using head and tail until the list is empty and accumulate some value at each call. The sum function below is a simple example to show this. This could be adapted to your example to accumulate acc when b or e are found in list A.
fun sum(numbers: (int) list) =
let fun sumR(numbers: (int) list, acc: int) =
if null numbers
then acc
else
sumR(tl numbers, hd numbers + acc)
in
sumR(numbers, 0)
end
Running on [1,2,3] gives:
val sum = fn : int list -> int
- sum([1,2,3]);
val it = 6 : int
Note I am intentionally vague with this answer since this is a question regarding Coursera homework for the Programming Languages class.
As you mention, it would be a nested/double loop in any imperative programming language. What you are actually missing is the second loop.
Your "inner" loop goes through all elements of d, and when this is done, your "outer" loop tries to pop the top element of m and start all over, as seen from this line of your code:
else if null d then number_in_months(d, tl m)
However as you can see, you have just tested the list d to be empty and you supply this (exact same list) to your recursive call on the tail of m, which will then fall in this same case for each successive call until m is also empty and you return 0.
Thus what you are missing is to "keep a copy" of the original input list m. This can be done in various ways, but an inner (helper) function is properly the most used one and it even "looks" like a nested loop
fun number_in_months (d, m) =
let
fun nim' ([], y::ys) = nim (d, ys) (* 1 *)
| nim' (_, []) = 0 (* 2 *)
| nim' ((_, x2, _) :: xs, yss as (y::ys)) = ... (* 3 *)
in
nim'(d, m)
end
Using pattern matching the above code gets much simpler and less error prone. In case 1, the "inner" loop has gone through all elements in d, thus the recursive call using d from the outer function which is not changed at any time. In case 2, the "outer" loop has gone through all elements of m and we return 0 (the neutral element of addition). In case 3 we do the actual work. Here pattern matching is used such that we don't need to enforce the type of the argument and we don't need to pull out the 2nd element of the triple, we already have it in the variable x2. All that is needed is to do the computation and make a recursive call with xs and yss.
When doing it this way, the inner (helper) function is using a "copy" of the original input list d and stepping through its elements (potentially modifying it), but we always got a reference to the original input list, which we can use if/when needed.