I have a function can_obtain to proof if a string init can be transformed to string target with the the following conditions:
string init and target only consist of letter "X" and/or "Y" (like "XY", "XXX", "YYXY", "Y", etc.)
string target is longer than init
options to get to target are
concatenate "X" to init or
reverse and concatenate "Y" to init
Here is the function, with trivial operations such as contains and reverse removed for terseness.
let can_obtain init target =
let final =
let rec reduce i text =
if i >= String.length target then text
else
let next =
let branchX = text ^ "X" in
let branchY = (reverse text) ^ "Y" in
if contains target branchX then branchX
else if contains target branchY then branchY
else text
in
reduce (i+1) next
in
reduce (String.length init) init
in
final = target
;;
Problem is with these transitions it returns true, which is correct
(* concat "X" only *)
(* "XY" -> "XYX" -> "XYXX" *)
can_obtain "XY" "XYXX";;
(* reverse and concat "Y" only *)
(* "XY" -> "YXY" -> "YXYY" -> "YXYYY" *)
can_obtain "XY" "YXYYY";;
(* reverse and concat "Y", then concat "X" lastly *)
(* "XY" -> "YXY" -> "YXYY" -> "YYXYY" -> "YYXYYX" *)
can_obtain "XY" "YYXYYX";;
However, if at some point in the transition "X" is concatenated, the function would refuse to switch to the reverse branch and just return false:
(* concat "X", then tries to reverse then concat "Y" *)
(* "XY" -> "XYX" -> "XYXY" *)
can_obtain "XY" "XYXY";; (* false *)
I know I'm missing just a small piece here, and the code looks really messy too. I would really appreciate some help.
can_obtain is a recursive function - so let's define the stop conditions first :
stop conditions:
if n=i then this is a success
if length i > length n then failure
If stop conditions are not met, then we have to go further and try with the 2 hypothesis : (init ^ "X"), ((reverse init) ^ "Y")
So the code results in :
let rec can_obtain init target =
if init = target then
true
else if String.length init >= String.length target then
false
else
(can_obtain (init ^ "X") target) || (can_obtain ((reverse init) ^ "Y") target)
Just looking at your code the obvious problem is that N might contain both branchX and branchY. In that case (it seems to me) you want to pursue both possibilities, but you're pursuing only the first.
Update
Another observation is that you probably want to pursue a branch if N contains the branch or its reverse. One of your operations reverses the string, and this operation might be applied an odd number of times for all you know.
Related
I am a new at F# and i try to do this task:
Make a function compare : string list -> string list -> int that takes two string lists and returns: -1, 0 or 1
Please help. I spend a lot of time, and i can not understand how to implement this task.
Given the task I assume what your professor wants to teach you with this exercise. I'll try to give you a starting point without
Confusing you
Presenting a 'done-deal' solution
I assume the goal of this task is to work with recursive functions and pattern matching to element-wise compare their elements. It could looks somewhat like this here
open System
let aList = [ "Apple"; "Banana"; "Coconut" ]
let bList = [ "Apple"; "Banana"; "Coconut" ]
let cList = [ "Apple"; "Zebra" ]
let rec doSomething f (a : string list) (b : string list) =
match (a, b) with
| ([], []) ->
printfn "Both are empty"
| (x::xs, []) ->
printfn "A has elements (we can unpack the first element as x and the rest as xs) and B is empty"
| ([], x::xs) ->
printfn "A is empty and B has elements (we can unpack the first element as x and the rest as xs)"
| (x::xs, y::ys) ->
f x y
printfn "Both A and B have elements. We can unpack them as the first elements x and y and their respective tails xs and ys"
doSomething f xs ys
let isItTheSame (a : string) (b : string) =
if String.Equals(a, b) then
printfn "%s is equals to %s" a b
else
printfn "%s is not equals to %s" a b
doSomething isItTheSame aList bList
doSomething isItTheSame aList cList
The example has three different lists, two of them being equal and one of them being different. The doSomething function takes a function (string -> string -> unit) and two lists of strings.
Within the function you see a pattern match as well as a recursive call of doSomething in the last match block. The signatures aren't exactly what you need and you might want to think about how to change the parametrization for cases where you don't want to stop the recursion (the last match block - if the strings are equal you want to keep on comparing, right?).
Just take the code and try it out in FSI. I'm confident, that you'll find the solution 🙂
In F# many collections are comparable if their element type is:
let s1 = [ "a"; "b" ]
let s2 = [ "foo"; "bar" ]
compare s1 s2 // -5
let f1 = [ (fun () -> 1); fun () -> 2 ]
let f2 = [ (fun () -> 3); fun () -> 42 ]
// compare f1 f2 (* error FS0001: The type '(unit -> int)' does not support the 'comparison' constraint. *)
so
let slcomp (s1 : string list) s2 = compare s1 s2 |> sign
Posting for reference as the original question is answered already.
I have a function confirm, which reads IO input, and depending by input, if it's y (yes) or n (no), it returns true/false, otherwise it calls confirm again, until any expected y or n is entered.
#spec confirm(binary) :: boolean
def confirm(question) do
answer = question |> IO.gets() |> String.trim() |> String.downcase()
case(answer) do
"y" -> true
"n" -> false
_ -> confirm(question)
end
end
To test y and n cases it's easy:
assert capture_io([input: "y"], fn -> confirm("Question") end) == "Question"
But I have no idea how to capture IO multiple times to test recursive case, let's say if at first input is "invalid" and then "y". Does elixir has any way to test IO functions like this? Or maybe do you have some suggestions how I could rewrite function to test it easier?
Original question https://elixirforum.com/t/testing-recursive-io-prompt/3715
Thanks for the help.
Untested, but what about just using newline characters?
assert capture_io([input: "foo\nbar\ny"], fn -> confirm("Question") end) == "Question"
I'm trying to consume an infinite list which may contain elements of type:
IO (Either Throwable a)
I'm only interested in consuming elements of type Right.
List is sorted. Right elements are always first and then Left elements
The problem is that the implementation I'm using is wrong because the function sequence evaluates the infinite list, so function never ends.
takeWhileRight :: [IO (Either Throwable a)] -> IO [(Either Throwable a)]
takeWhileRight list = do
unwrappedList <- sequence $ list -- BANG!!
return $ takeWhile isRight $ unwrappedList
isRight :: (Either Throwable a) -> Bool
isRight x = case x of
Right x -> true
Left x -> false
Any ideas about how to consume that list properly ?
Yes, this doesn't work with sequence
You need to do something like
takeWhileRight (x:xs) = do
y <- x
case y of
Right -> (y:) <$> takeWhileRight xs
Left -> pure []
takeWhileRight [] = pure []
(Untested.)
Note that the first IO action that gives a Left will still have to be run. This is unavoidable.
I'm new to ocaml and tryin to write a continuation passing style function but quite confused what value i need to pass into additional argument on k
for example, I can write a recursive function that returns true if all elements of the list is even, otherwise false.
so its like
let rec even list = ....
on CPS, i know i need to add one argument to pass function
so like
let rec evenk list k = ....
but I have no clue how to deal with this k and how does this exactly work
for example for this even function, environment looks like
val evenk : int list -> (bool -> ’a) -> ’a = <fun>
evenk [4; 2; 12; 5; 6] (fun x -> x) (* output should give false *)
The continuation k is a function that takes the result from evenk and performs "the rest of the computation" and produces the "answer". What type the answer has and what you mean by "the rest of the computation" depends on what you are using CPS for. CPS is generally not an end in itself but is done with some purpose in mind. For example, in CPS form it is very easy to implement control operators or to optimize tail calls. Without knowing what you are trying to accomplish, it's hard to answer your question.
For what it is worth, if you are simply trying to convert from direct style to continuation-passing style, and all you care about is the value of the answer, passing the identity function as the continuation is about right.
A good next step would be to implement evenk using CPS. I'll do a simpler example.
If I have the direct-style function
let muladd x i n = x + i * n
and if I assume CPS primitives mulk and addk, I can write
let muladdk x i n k =
let k' product = addk x product k in
mulk i n k'
And you'll see that the mulptiplication is done first, then it "continues" with k', which does the add, and finally that continues with k, which returns to the caller. The key idea is that within the body of muladdk I allocated a fresh continuation k' which stands for an intermediate point in the multiply-add function. To make your evenk work you will have to allocate at least one such continuation.
I hope this helps.
Whenever I've played with CPS, the thing passed to the continuation is just the thing you would normally return to the caller. In this simple case, a nice "intuition lubricant" is to name the continuation "return".
let rec even list return =
if List.length list = 0
then return true
else if List.hd list mod 2 = 1
then return false
else even (List.tl list) return;;
let id = fun x -> x;;
Example usage: "even [2; 4; 6; 8] id;;".
Since you have the invocation of evenk correct (with the identity function - effectively converting the continuation-passing-style back to normal style), I assume that the difficulty is in defining evenk.
k is the continuation function representing the rest of the computation and producing a final value, as Norman said. So, what you need to do is compute the result of v of even and pass that result to k, returning k v rather than just v.
You want to give as input the result of your function as if it were not written with continuation passing style.
Here is your function which tests whether a list has only even integers:
(* val even_list : int list -> bool *)
let even_list input = List.for_all (fun x -> x mod 2=0) input
Now let's write it with a continuation cont:
(* val evenk : int list -> (bool -> 'a) -> 'a *)
let evenk input cont =
let result = even_list input in
(cont result)
You compute the result your function, and pass resultto the continuation ...
Can someone give me the difference between these two kinds recursions and example (specifically in OCaml)?
A tail recursive function is a function where the only recursive call is the last one in the function. A non-tail recursive function is a function where that is not the case.
A backward recursion is a recursion where in each recursive call the value of the parameter is less than in the previous step. A forward recursion is a recursion where it grows bigger with each step.
Those are two orthogonal concepts, i.e. a forward recursion may or may not be tail-recursive and the same applies to backward recursions.
For example the factorial function is often written like this in imperative languages:
fac = 1
for i from 1 to n:
fac := fac * i
The common recursive version of factorial counts backwards (i.e. it calls itself with n-1 as the parameter), however if you'd directly translate the above imperative solution, you'd come up with a recursive version that counts upwards. It would look something like this:
let fac n =
let rec loop i =
if i >= n
then i
else i * loop (i+1)
in
loop 1
This is a forward recursion and as you can see it is slightly more cumbersome than the backward recursive variant as it requires a helper function. Now this is not tail recursive as the last call in loop is the multiplication, not the recursion. So to make it tail-recursive, you'd do something like this:
let fac n =
let rec loop acc i =
if i >= n
then acc
else loop (i*acc) (i+1)
in
loop 1 1
Now this is both a forward recursion and a tail recursion because the recursive call is a) a tail-call and b) calls itself with a greater value (i+1).
Here's an example of a tail recursive factorial function:
let fac n =
let rec f n a =
match n with
0 -> a
| _ -> f (n-1) (n*a)
in
f n 1
Here is it's non-tail recursive counterpart:
let rec non_tail_fac n =
match n with
0 -> 1
| _ -> (non_tail_fac n-1) * n
The tail recursive function uses an accumulator, a, to store the value of the result of the previous call. This allows OCaml to perform tail call optimization which results in the the stack not overflowing. Typically a tail recursive function will make use of an accumulator value to allow tail call optimization to occur.
For example, a recursive function build_word which takes a char list and combine them to a string i.e.['f'; 'o'; 'o'] to string "foo". The induction process can be visualized this way:
build_word ['f'; 'o'; 'o']
"f" ^ (build_word ['o'; 'o'])
"f" ^ ("o" ^ (build_word ['o']) // base case! return "o" and fold back
"f" ^ ("o" ^ ("o"))
"f" ^ ("oo")
"foo"
That was a normal recursion. Note that each pair of parentheses stands for a new stack frame or recursive call. The solution to this problem (i.e. "f", "fo", or "foo") cannot be derived before the end of the recursion (where the base case is met). Only then does the last frame return the last result back to the previous one before "popping", and vice versa.
In theory, each call creates a new stack frame (or scope, if you will) to hold the "place" for the fragmented solution to be returned and collected toward the beginning. This can leads to stackoverflow (this link is a recursion btw).
A tail call version would look something like this:
build_word ['f'; 'o'; 'o'] ""
build_word ['o'; 'o'], "f"
build_word ['o'] ("f" ^ "o")
build_word [] ("f" ^ "o" ^ "o")
"foo"
Here, the accumulated result (often stored in a variable known as accumulator) is being passed forward. With optimization, tail call wouldn't have to create a new stack frame because it does not have to maintain the previous ones. The solution is being solved "forward" rather than "backward".
Here are the build_word functions in two versions:
non-tail
let build_word chars =
match chars with
| [] -> None
| [c] -> Some Char.to_string c
| hd :: tl -> build_word tl
tail
let build_word ?(acc = "") chars =
match chars with
| [] -> None
| [c] -> Some Char.to_string c
| hd::tl -> build_word ~acc:(acc ^ Char.to_string hd) tl
The forward recursion is well-explained in the accepted answer by #sepp2k.