Matching Patterns for list of tuples - f#

I'm trying to write a fcn that takes in a list of tuple and an expression (I am working on a postfix expression eval). This function should loop through the expression and find the same letter in the tuple. If it's a match then it returns the int value corresponding to that letter in the tuple. When I ran the code below, my program compiled and run but then it was hanging during execution. What did I do wrong?
let rec getVar ls exp =
match ls with
|head::tl when (fst head) = exp -> printfn "%d" (snd head)
| _ -> getVar ls exp
let ls = [("a",5);("b",2);("c",3)]
let exp = "ab+"
getVar ls exp

Your match expression has a final catch-all clause (the _ clause) that just calls getVar again with the same parameters. If the when (fst head) = exp condition fails, then code falls through to the catch-all clause, so getVar gets called again with the same parameters, so the first condition will fail, so code falls through to the catch-all clause, so getVar gets called again... It's an infinite loop.
What you probably meant to do was call getVar again on the tail of the list if your when condition failed:
match ls with
|head::tail when (fst head) = exp -> printfn "%d" (snd head)
|head::tail -> getVar tail exp
You also need to think about what you'll do if the list is empty (i.e., you need a match condition that matches against []). I'll leave that one up to you, since there are many things you could want to do with an empty list and it's not obvious which one you'd want.

Your match must handle three cases.
Empty list -> return some default value (or unit without side effects)
Match found -> return a value or trigger some side effect.
Match not yet found -> keep searching in tail of list.
In your first attempt, you accidentally kept searching in the whole list instead of merely the tail, resulting in an endless recursive loop.
In your second attempt, you instead created an infinite loop in the empty case.
Below is one example of how you might write the recursive function.
let rec getVar ls exp =
match ls with
|[] -> None
|head::tail when (fst head) = exp -> Some <| sprintf "%d" (snd head)
|head::tail -> getVar tail exp
let ls = [("a",5);("b",2);("c",3)]
let result1 = getVar ls "ab+" // result = None
let result2 = getVar ls "b" // result = Some "2"

The signature of your getVar function is wrong. The last parameter should be a letter of the expression, not the whole expression. The code calling the getVar function would go through the expression, for each character, check if it is a letter, if yes then call getVar, otherwise then do other things.
The reason why you code gets hanged is explained clearly in the other answers so I won’t repeat here. But as a good practice, please don’t use | _ -> ... unless you totally control the situation. Typically, we should explicitly write all the matching conditions, so that if we miss something, compiler will warn us. After that, when being aware all the conditions, we can use | _ -> ... if it really means “the rest conditions”.
Your getVar function can be rewritten as:
let rec getVar ls letter =
match ls with
| [] -> ()
| head :: tail when fst head = letter -> printfn "%d" (snd head)
| _ :: tail -> getVar tail letter
I suggest you learn the common built-in functions of F# core library. So you can use the List.tryFind function in your problem:
let getVar ls letter =
ls |> List.tryFind (fun (key, value) ->
if key = letter then
printfn "%d" value
true
else false)
The more you can use bult-in functions, the less bugs you have.

Related

F# - Insert element in sorted list (tail-recursive)

I am trying to convert the following normal-recursive code to tail-recursive in F#, but I am failing miserably.
let rec insert elem lst =
match lst with
| [] -> [elem]
| hd::tl -> if hd > elem then
elem::lst
else
hd::(insert elem tl)
let lst1 = []
let lst2 = [1;2;3;5]
printfn "\nInserting 4 in an empty list: %A" (insert 4 lst1)
printfn "\nInserting 4 in a sorted list: %A" (insert 4 lst2)
Can you guys help? Unfortunately I am a beginner in f#. Also, can anyone point me to a good tutorial to understand tail-recursion?
The point of tail recursion is the following: the last operation before returning from a function is a call to itself; this is called a tail call, and is where tail recursion gets its name from (the recursive call is in last, i.e. tail position).
Your function is not tail recursive because at least one of its branches has an operation after the recursive call (the list cons operator).
The usual way of converting a recursive function into a tail-recursive function is to add an argument to accumulate intermediate results (the accumulator). When it comes to lists, and when you realize that the only elementary list operation is prepending an element, this also means that after you are through with processing your list, it will be reversed, and thus the resulting accumulator will usually have to be reversed again.
With all these points in mind, and given that we do not want to change the function's public interface by adding a parameter that is superfluous from the caller's point of view, we move the real work to an internal subfunction. This particular function is slightly more complicated because after the element has been inserted, there is nothing else to do but concatenate the two partial lists again, one of which is now in reverse order while the other is not. We create a second internal function to handle that part, and so the whole function looks as follows:
let insert elm lst =
let rec iter acc = function
| [] -> List.rev (elm :: acc)
| (h :: t) as ls ->
if h > elm then finish (elm :: ls) acc
else iter (h :: acc) t
and finish acc = function
| [] -> acc
| h :: t -> finish (h :: acc) t
iter [] lst
For further studying, Scott Wlaschin's F# for Fun and Profit is a great resource, and tail recursion is handled in a larger chapter about recursive types and more: https://fsharpforfunandprofit.com/posts/recursive-types-and-folds

Haskell & Language Design: Design Struggle in implementing Do-While Loop for imperative language

I'm designing an imperative language but I'm having issues in implementing loop functionality. A loop would take the following form:
Do (n < 10)->
Loop Body
I can parse a loop correctly however when it comes to evaluating the loop, two problems arise. The first is I can't exit loop without returning a faux exit success code, though I do think it's because of how I'm implementing the loop. The second issue is that I can't evaluate the body of the loop when there exists more than one expression. I discovered this because I originally had my loop represented as follows:
data HVal
= HInteger Integer
| HBool Bool
| HString String
| HList [HVal]
| Expr HVal Op HVal -- Arithmetic, Relational, and Boolean
| Assign String HVal
| Do HVal HVal
In this instance the following evaluation function for a loop works when the body consists of a single expression:
evalDo :: Env -> HVal -> HVal -> IOThrowsError HVal
evalDo env cond expr = eval env cond >>= \x -> case x of
HBool True -> eval env expr >>= \y -> eval env $ Do cond y
HBool False -> return $ HInteger 1
This function evaluates the following loop correctly:
n := 0
Do (n < 10)->
n := (n + 1)
When it came to evaluating a longer loop body I found that it made more sense to change the loop representation to:
Do HVal [HVal]
My logic behind this is that a loop will consist of the guard and then a list of expressions to be evaluated upon in the loop body. I then made a change to evalDo:
evalDo :: Env -> HVal -> [HVal] -> IOThrowsError HVal
evalDo env cond expr = eval env cond >>= \x -> case x of
HBool False -> return $ HInteger 1
HBool True -> do
y <- return $ map (\x -> eval env x) expr
eval env $ Do cond expr
This however causes the following loop to go into an infinite loop:
n := 0
r := 1
Do (n < 10)->
n := (n + 1)
r := (r * 2)
I think the problem stems from the return when I evaluate the expression but I receive the following error when I don't have it:
Couldn't match type ‘[]’ with ‘ExceptT HError IO’
Expected type: ExceptT HError IO (IOThrowsError HVal)
Actual type: [IOThrowsError HVal]
Any guidance or help on this would be great.
The first is I can't exit loop without returning a faux exit success code, though I do think it's because of how I'm implementing the loop.
To avoid that issue, imperative languages commonly define their syntax in two levels, expressions, like 1 + 2, which have values, and statements, like loops, which don't have values, but their point is their side effects. Expressions are also often considered a subset of statements by ignoring their value. Following that approach, your syntax could be reorganized to look like this:
data Expr
= HInteger Integer
| Expr Expr Op Expr
data Stmt
= Block [Stmt]
| Do Expr Stmt
| Assign Var Expr -- In C, an assignment is actually an expression, but it is widely considered a misfeature.
| Eval_ Expr
(...) This however causes the following loop to go into an infinite loop:
In your interpretation of Do, you are using map, which only constructs a list of computations, but you need to compose those computations into a single one.
Use traverse_ from Data.Foldable.
-- traverse_ (\x -> eval env x) expr
-- or shorter, --
traverse_ (eval env) expr
eval env ...
As a tip for diagnosing that issue, you can tell that something is wrong from reading the code because y <- return ..., where y is not used later, is always a noop, so
_ <- return $ map (\x -> eval env x) expr
eval env ...
because of return, that is the same as
eval env ...
whereas you didn't mean to ignore the map ... part.

f# remove from own user defined list

I want to create a function that removes any occurrence of a integer n and returns the list. I know how I want to do it but do not know the command to delete it.
Here is the data type
type alist =
A
| L of int * Alist
Here's how the data type looks:
let l = L(2, L(1, L(2, L(7, L(3, L(2, A))))))
remove 2 l;;
should return
l = L(1, L(7, L(3, A)))
Here is what I have so far:
let rec remove n l =
match (n, l) with
| (n, A) -> l
| (n, L(head,tail)) when (n = head) ->
I don't know how the how to get rid of a list or element.
You shouldn't be thinking in terms of "deleting" the list; you should instead think in terms of building a new list, without the element you want removed. I'll show you how to do that in a minute, but first I want to make a suggestion. In your match expression, you are re-using the name n in your patterns. That's a classic beginner's mistake, because it ends up confusing you. Once you know F# pretty well, that's a valid technique, but since you appear to be a beginner, I strongly suggest not doing that. Instead, use a name in your patterns that is different from the name of the thing you're matching against, because that will help teach you something. Let's rewrite your match expression with x as the name of the int in your patterns:
let rec remove n l =
match (n, l) with
| (x, A) -> l
| (x, L(head,tail)) when (x = head) ->
What each of these two patterns is doing is assigning the name x to represent the value of n if the rest of the pattern matches. Now we can more clearly see that the first pattern doesn't use the value of x at all, so it would be better to represent it by _ in that case (_ is the "wildcard" pattern, which means "I don't care about the value in this position). Thus, your match expression would become:
let rec remove n l =
match (n, l) with
| (_, A) -> l
| (x, L(head,tail)) when (x = head) -> // ... Still need to write this
Now let's think about what we want to do in that second match case. Here we have a node that is precisely the kind of node we want to remove from the list. So how do we go about building a list without that node in it? Well, as it happens, we already have such a list... and we've assigned it the name tail in that second match case. So at first, it might look like we could just do this:
let rec remove n l =
match (n, l) with
| (_, A) -> l
| (x, L(head,tail)) when (x = head) -> tail
This will return a list with the "head" node chopped off. But wait! What if the tail itself contained one or more nodes with the value we want removed? What we'd really like to return from this match case is tail, passed through a function that would remove all the nodes that match a certain value. But... wait a minute... aren't we writing a function like that right now? What if we could just call remove on the tail and have it do the rest of the work for us; wouldn't that be nice?
Well, it turns out that we can! All you have to do to remove the rest of the unwanted values from the tail list is to call remove on it! Like so:
let rec remove n l =
match (n, l) with
| (_, A) -> l
| (x, L(head,tail)) when (x = head) -> remove n tail
But we're not quite done yet, because there's one more possibility in your match statement. If you are using a good F# development environment (I recommend Visual Studio Code with the Ionide plugin), you should see a green wavy underline under the match keyword, and if you hover over it you should see a warning about an incomplete match expression. That's because there's one case we haven't accounted for: the case where l is a node that isn't A, but whose head value isn't equal to n. In other words, this match case:
| (x, L(head,tail)) when (x <> head) -> // What do we do here?
Well, for starters, let's simplify this match case a bit. If we put it into the complete match expression, we should see that the when guard is actually unnecessary. Match cases are checked from top to bottom, in order. Which means that if we get to the third match case, we already know that x must not be equal to head; otherwise the second match case would have been chosen! You may not be able to see why just yet, so let's put that match case into our match expression and take a look at it:
let rec remove n l =
match (n, l) with
| (_, A) -> l
| (x, L(head,tail)) when (x = head) -> remove n tail
| (x, L(head,tail)) when (x <> head) -> // What do we do here?
Now it's more obvious that this exactly like the previous match case, but with the opposite when guard. Which means that if we ever reach the third match case, the when expression must be true -- because if it was false, then that means that x is equal to head and so we would have gone down the second match case, not the third.
Therefore, we can actually remove the when guard from the third match case, which will now look like this:
let rec remove n l =
match (n, l) with
| (_, A) -> l
| (x, L(head,tail)) when (x = head) -> remove n tail
| (x, L(head,tail)) -> // What do we do here?
There's more simplification that can be done here, but it's time to look at what result we want to return. Here, we do NOT want to skip the first node of the list, but we'd still like to remove n from the tail. In fact, what we want as a result of this function is a list node containing the same head as our current list node, but with a tail that has had n removed from it. (If you don't understand that last sentence, take a minute and try to picture this in your head.) So how do we do this? Well, the simplest way is as follows:
let newTail = remove n tail
L(head, newTail)
Which can be simplified to:
L(head, remove n tail)
So the match function looks like this now:
let rec remove n l =
match (n, l) with
| (_, A) -> l
| (x, L(head,tail)) when (x = head) -> remove n tail
| (x, L(head,tail)) -> L(head, remove n tail)
Believe it or not, we're done! Well, almost: we have a working function now, but it's actually more complicated than it needs to be. Antoine de Saint-Exupéry is most well-known for writing The Little Prince, but he was also an aviator, who has a famous quote about design:
Il semble que la perfection soit atteinte non quand il n'y a plus rien à ajouter, mais quand il n'y a plus rien à retrancher.
In English, that's:
It seems that perfection is attained not when there is nothing more to add, but when there is nothing more to remove.
So what can we remove from this function to pare it down to the absolute essentials? Well, let's start by looking at that last match case again:
| (x, L(head,tail)) -> L(head, remove n tail)
It looks like we don't use the value of x anywhere in this match case, so we don't actually need to assign a name to the int in this match case. We can just use the wildcard _ here. Once we do, our function looks like:
let rec remove n l =
match (n, l) with
| (_, A) -> l
| (x, L(head,tail)) when (x = head) -> remove n tail
| (_, L(head,tail)) -> L(head, remove n tail)
And at this point, you might think that we're really done, because we do use the value of x in the second match case, so we can't get rid of it. Or... can we? Let's look at the second match case more closely:
| (x, L(head,tail)) when (x = head) -> remove n tail
Now. The value of x here is the same as the value of n, because this match case is actually assigning the value of n to the name x by virtue of x being in the first tuple position. Right? So in the when guard, we could actually swap out x for n in the x = head check. This is legal: the checks that you do in a match case do NOT have to include only names that have appeared in the match pattern. They can be any names that your function has access to. So it's perfectly valid to swap x out for n and get the match case to look like this:
| (x, L(head,tail)) when (n = head) -> remove n tail
And now we see that we're not using the value of x in this match case either, just like in the third match case. So let's get rid of it:
| (_, L(head,tail)) when (n = head) -> remove n tail
Now let's put this match case back into our function and take a look at the function as a whole:
let rec remove n l =
match (n, l) with
| (_, A) -> l
| (_, L(head,tail)) when (n = head) -> remove n tail
| (_, L(head,tail)) -> L(head, remove n tail)
Huh. Would you look at that? The first tuple item has "I don't care" in every single spot in the match case. And yet, the function still compiles without warning about incomplete match patterns, and still runs and produces the correct values. (Try it!) So what does this tell us? It tells us that we don't actually need to have n in the value we're matching against, because we never need it in the match patterns. We need it in the when guards, but not in the match patterns themselves! So if we actually remove n from the value we're matching against, and from the match patterns, here's the result:
let rec remove n l =
match l with
| A -> l
| L(head,tail) when (n = head) -> remove n tail
| L(head,tail) -> L(head, remove n tail)
Try it. You'll see that this function also compiles, and still does exactly what you want it to do.
At this point, we really are done. Taking away anything else from this function would break it: either it wouldn't compile, or else it wouldn't return the right value. This may not be immediately obvious to you, but as your skill with F# grows, you'll learn to get a feel for when a function has been pared down to its bare essentials, and this one has.
And so there you go: after a lot of tweaking, we've gotten the remove function not just working, but working elegantly. This is the simplest you can possibly make this function, and there's a certain beauty in that. If you can see and appreciate that beauty, the beauty of a function that does exactly what it should and no more, you'll be well on your way to becoming a skilled F# programmer!
P.S. There is actually one more rewrite that we could do on this function, because it actually could be better. As it stands, this function is not always tail-recursive, which means that if you called it on a really large list, you could get a StackOverflowException. But if you haven't reached the point of studying tail recursion yet, then trying to explain how to fix this problem would be like to confuse you rather than help you understand things better. So I've deliberately chosen to end with this pared-down, elegant version of the function, rather than the version that does tail recursion "properly". Because making that improvement would produce a function that was actually more complicated and harder to understand. Once you're more experienced with F#, it'll be worth revisiting this question and asking "How do I make this function tail-recursive?". But for now, the non-tail-recursive version that we have here is the one that you should study. Once you understand how to write this function on your own, and can write other list-manipulation functions on your user-defined list data structure, then you'll have the knowledge needed to make that last improvement.
I hope this helps. Please leave a comment asking me about anything you don't understand in my explanation.

Using continuation to transform binary recursion to tail recursion

As I'm reading the Programming F# book, I found the example code snippet on page 195 as follows:
type ContinuationStep<'a> =
| Finished
| Step of 'a * (unit -> ContinuationStep<'a>)
let iter f binTree =
let rec linearize binTree cont =
match binTree with
| Empty -> cont()
| Node(x, l, r) ->
Step(x, (fun () -> linearize l (fun() -> linearize r cont)))
let steps = linearize binTree (fun () -> Finished)
let rec processSteps step =
match step with
| Finished -> ()
| Step(x, getNext)
-> f x
processSteps (getNext())
processSteps steps
By using continuation, the binary recursion of traversing a binary has been transformed to tail-recursive function processSteps. My question is that the other function, linearize seems to be non-tail-recursive. Does that mean we are not able to transform a binary-recursion to a tail-recursion completely even using continuation?
linearize is tail-recursive: you don't need to come back from the recursive call to continue the computation.
fun () -> linearize l (fun() -> linearize r cont)
doesn't call linearize. The computation is suspended until processSteps calls getNext ().
The example is a bit subtle because it does not use ordinary continuations, but instead builds a structure that can be evaluated step-by-step. In a place where you would normally make a recursive call, it returns a value Step that contains the function that you'd (recursively) call.
In the second case, the linearize function returns a Step containing a function that will call linearize recursively, but it does not immediately make the recursive call. So the function does not make a recursive call (it just stores a recursive reference).
It only makes sense to consider whether the program is tail-recursive when you look at processSteps, because that does the actual looping - and that is tail-recursive, because it runs a Step by Step without keeping stack space for each Step.
If you wanted to construct a list instead of a chain of lazy steps then you'd have to make the recursive call to linearize immediately inside the continuation:
let rec linearize binTree cont =
match binTree with
| Empty -> cont []
| Node(x, l, r) ->
linearize l (fun l -> linearize r (fun v -> cont (x::v)))
This is essentially the same as the previous function, but it actually calls linearize instead of building Step containing a function that will call linearize.

Conversion to tail recursion

Hey guys, I'm trying to get cozy with functional programming (particularly with F#), and I've hit a wall when it comes to building tail-recursive functions. I'm pretty good with turning basic recursion (where the function basically calls itself once per invocation), into tail recursion, but I now have a slightly more complicated situation.
In my case, the function must accept a single list as a parameter. When the function is called, I have to remove the first element from the list, and then recur using the remainder of the list. Then I need to apply the first element which I removed in some way to the result of the recursion. Next, I remove the second element and do the same thing (Note: when I say "remove the seond element", that is from the original list, so the list passed at the recursion includes the first element as well). I do the same for the third, fourth, etc. elements of the list.
Is there a way to convert the above situation into a tail-recursive function? Maybe nested tail-recursive functions??? Thank you for any answers.
Okay, so here's my basic code. This particular one is a permutation generator (I'm not too concern with the permutation part, though - it's the recursion I'd like to focusing on):
let permutationsOther str =
match str with
| value :: [] ->
[[value]]
| _ ->
let list = (List.map (fun a -> // This applies the remove part for every element a
let lst = (List.filter (fun b -> b <> a) str) // This part removes element a from the list
let permutedLst = permutations lst // recursive call
consToAll a permutedLst // constToAll this is my own function which performs "cons" operation with a and every element in the list permutedLst
) str)
List.reduce (fun acc elem -> elem # acc) list // flatten list of lists produce by map into a single list
I hope this is clear enough - I'll be happy to provide clarifications if needed.
By the way, I have found just a way to rewrite this particular function so that it only uses a single recursion, but it was a fluke more than an informed decision. However, this has encouraged me that there may be a general method of turning multiple recursion into single recursion, but I have not yet found it.
Conversion to CPS should do the trick:
NOTE 1: Source of the sample is typed directly in browser, so may contain errors :(. But I hope it can demonstrate the general idea.
NOTE 2: consToAll function should be converted to CPS too: consToAll: 'T -> 'T list list -> ('T list list -> 'R) -> 'R
let remove x l = List.filter ((<>) x) l // from original post: should duplicates also be removed ???
let permute l =
let rec loop k l =
match l with
| [] -> k []
| [value] -> k [[value]]
| _ -> filter l [] l (fun r -> r |> List.reduce (fun acc elem -> elem # acc) |> k )
and filter l acc orig fk =
match l with
| [] -> fk acc
| x::xs ->
remove x orig
|> loop (fun res ->
consToAll x res (fun rs -> filter xs (rs::acc) orig fk)
)
loop id l

Resources