How to let OCaml function returns a tuple containing a string and a function? - function

Eventually what I want is what x represents:
let x = (something, (myfunc1 para1));;
so that when calling x, I get a tuple, but when calling (snd x) para, I will get a return value of myfunc1 para.
What I'm trying is like this:
let myfunc2 para1 para2 =
let myfunc1 para2 = ... in
( (fst para1), (myfunc1 para2) );;
And I want to call myfunc2 like this:
let x = myfunc2 para1 to get what I described above. However, what I get is just a function which when called with para1 will return a regular tuple, not a (something, function) tuple

You have a useless para2 parameter in your definition. The correct way is:
let myfunc2 para1 =
let x = ... in
let myfunc1 para2 = ... in
( x, myfunc1 );;
But it would help if we could speak about a concrete example. You are misunderstanding something obvious, but I do not know what.
Here is a concrete example. Suppose we want a function f which accepts a number n and returns a pair (m, g) where m is the square of n and g is a function which adds n to its argument:
let f n =
let m = n * n in
let g k = n + k in
(m, g)
Or shorter:
let f n = (n * n, fun k => n + k)
Now to use this, we can do:
let x = f 10 ;;
fst x ;; (* gives 100 *)
snd x ;; (* gives <fun> *)
snd x 5 ;; (* gives 15, and is the same thing as (snd x) 5 *)
Now let us consider the following bad solution in which we make the kind of mistake you have made:
let f_bad n k =
let m = n * n in
let g k = n + k in
(m, g k)
Now f_bad wants two arguments. If we give it just one, we will not get a pair but a function expecting the other argument. And when we give it that argument, it will return a pair of two integers because (m, g k) means "make a pair whose first component is the integer m and the second component is g applied to k, so that is an integer, too."
Another point worth making is that you are confusing yourself by calling two different things para2. In our definition of f_bad we also confuse ourselves by calling two different things k. The k appearing in the definition of g is not the same as the other k. It is better to call the two k's different things:
let f_bad n k1 =
let m = n * n in
let g k2 = n + k2 in
(m, g k1)
Now, does that help clear up the confusion?

Related

How to fix this type error when computing a list of divisors?

I am working on the following exercise:
Define a function libDiv which computes the list of natural divisors of some positive integer.
First define libDivInf, such that libDivInf n i is the list of divisors of n which are lesser than or equal to i
libDivInf : int -> int -> int list
For example:
(liDivInf 20 4) = [4;2;1]
(liDivInf 7 5) = [1]
(liDivInf 4 4) = [4;2;1]
Here's is my attempt:
let liDivInf : int -> int -> int list = function
(n,i) -> if i = 0 then [] (*ERROR LINE*)
else
if (n mod i) = 0 (* if n is dividable by i *)
then
i::liDivInf n(i-1)
else
liDivInf n(i-1);;
let liDiv : int -> int list = function
n -> liDivInf n n;;
I get:
ERROR: this pattern matches values of type 'a * 'b ,but a pattern
was expected which matches values of type int
What does this error mean? How can I fix it?
You've stated that the signature of liDivInf needs to be int -> int -> int list. This is a function which takes two curried arguments and returns a list, but then bound that to a function which accepts a single tuple with two ints. And then you've recursively called it in the curried fashion. This is leading to your type error.
The function keyword can only introduce a function which takes a single argument. It is primarily useful when you need to pattern-match on that single argument. The fun keyboard can have multiple arguments specified, but does not allow for pattern-matching the same way.
It is possible to write a function without using either.
let foo = function x -> x + 1
Can just be:
let foo x = x + 1
Similarly:
let foo = function x -> function y -> x + y
Can be written:
let foo x y = x + y
You've also defined a recursive function, but not included the rec keyword. It seems you're looking for something much more like the following slightly modified version of your attempt.
let rec liDivInf n i =
if i = 0 then
[]
else if (n mod i) = 0 then
i::liDivInf n (i-1)
else
liDivInf n (i-1)

How to define a function with Church numerals in lambda-terms?

How can I express the following function by a lambda term?
f(n) = T if n != 0.
F if n = 0.
n stands for a Church numeral.
I know that 0 := λf.λx.x where λx.x is the identity function and all other natural numbers can be expressed by n := λf.λx.f (f ... (f x)) which contains f n times more than the 0-term. E.g. 3 := λf.λx.f (f (f x)).
But how can I derive a valid λ-term for the function above? I think I need a y too for getting the T/F. Therefore I can express the number n by λf.(λxy.fxy), right? But what about the F and T? Is the following a right λ-term for the function above? λf.(λxy.fxy(yFT)) where T=λxy.x and F=λxy.y?
No, you're given the term for n. It is a function that expects two arguments, an f and a z:
isZero n = n ( ;; f, a function, expecting x
;; or the result of (f (f ... (f x) ...))
λx.
;; but we know what we want it to return, always: it is:
F ;; false, for n is _not_ 0
)
( ;; the initial x, in case n is ......... 0!
;; so we know what we want it to be, in case n is 0:
T ;; true, for n _is_ 0
)
and thus
isZero = λn.n(λx.F)T
If n was 0, isZero n will return T; and otherwise, F:
{0}(λx.F)T = T
{1}(λx.F)T = (λx.F)T = F
{2}(λx.F)T = (λx.F)((λx.F)T) = F
{3}(λx.F)T = (λx.F)((λx.F)((λx.F)T)) = F
....

Recursive Function that divides two integers and returns result and remainder

I am trying to create a recursive function that divides two integers n and m and then displays the result and the remainder of the division.
Basicly I created two separate functions which do exactly what I want:
let rec div1 (n: int, m: int): int =
if n<m then n else div1(n-m, m)
printfn "Remainder: %i" (div1(5,5))
let rec div2 (n: int, m: int): int =
if n<m then 0 else 1+div2(n-m, m)
printfn "Result: %i" (div2(5,5))
The thing is, I want to do them both at once, I mean in one function like let rec div12 (n: int) (m : int): int * int = , not in two separate.
I am not sure how exactly this would work on F#.
A function may return more than just a number. For example, a function may return a tuple of two numbers:
let f x = (x, x+5)
f 5
> (5, 10)
Further, you can destructure return value of such a function in a similar way:
let (x, y) = f 5
x
> 5
y
> 10
Now we can use this to have our div+mod function return two results - remainder and quotient:
let rec divMod n m =
if n < m
then
(n, 0)
else
let (remainder, quotient) = divMod (n-m) m
(remainder, quotient + 1)
Note how this function simply combines results of your div1 and div2 in a tuple, then destructures them after the recursive call.
divMod 5 5
> (0, 1)
divMod 5 3
> (2, 1)
divMod 7 3
> (1, 2)
Also note that I'm using curried parameters divMod n m instead of tupled parameters as you do div1 (n, m). Ultimately this is a matter of taste, but as a pro tip, I'd like to point out that curried parameters turn out to be much more useful in practice.

Trouble computing recursive value of this function

let rec f (l: int list) : int * int =
begin match l with
| [] -> (0,0)
| [x] (x,x)
| x::y::tl -> let (a,b) = f tl in
(x + a, y + b)
end
let r = f [2;3;4;5;6]
I'm thinking that the answer would compute to r = (6,6) because if you keep calling the recursive function on the tail, you'll end up with the last item in the list, thus it will match to the second case but I have no idea if this is correct or why this is the case. Really, I don't understand the use of let (a,b) = f tl in (x + a, y + b).
I'll try to explain let (a, b) = f tl in (x + a, y + b). Maybe that will help.
The pattern for this case is x :: y :: tl. So this means that tl represents the tail of the tail of the list. I.e. it represents the list after you remove the two elements at the front.
Along these same lines, x represents the first element of the list and y represents the second element.
The recursive call to f is going to return whatever f returns for tl, which is what you're trying to figure out. This will be a pair of numbers, as you can tell from the pattern (a, b).
The result of the whole expression (which is the result of f except when the list is very short) is (x + a, y + b). In other words, it adds the first element of the list to the first number of the pair and the second element of the list to the second element of the pair.

Putting last element of list in the first index "n" times SML

I'm trying to put the last element of a list in the front of the list while keeping the rest of the elements in the same order N times. I can do it once with this function, but I want to add another parameter to the function so that the function in called N times.
Code:
fun multcshift(L, n) =
if null L then nil
else multcshift(hd(rev L)::(rev(tl(rev L))));
Thanks
To make the parameter n work, you need recursion. You need a base case at which point the function should no longer call itself, and a recursive case where it does. For this function, a good base case would be n = 0, meaning "shift the last letter in front 0 times", i.e., return L without modification.
fun multcshift(L, n) =
if n = 0
then L
else multcshift( hd(rev L)::rev(tl(rev L)) , n - 1 )
The running time of this function is terrible: For every n, reverse the list three times!
You could save at least one of those list reversals by not calling rev L twice. E.g.
fun multcshift (L, 0) = L
| multcshift (L, n) =
let val revL = rev L
in multcshift ( hd revL :: rev (tl revL) , n - 1 ) end
Those hd revL and rev (tl revL) seem like useful library functions. The process of applying a function to its own output n times seems like a good library function, too.
(* Return all the elements of a non-empty list except the last one. *)
fun init [] = raise Empty
| init ([_]) = []
| init (x::xs) = x::init xs
(* Return the last element of a non-empty list. *)
val last = List.last
(* Shift the last element of a non-empty list to the front of the list *)
fun cshift L = last L :: init L
(* Compose f with itself n times *)
fun iterate f 0 = (fn x => x)
| iterate f 1 = f
| iterate f n = f o iterate f (n-1)
fun multcshift (L, n) = iterate cshift n L
But the running time is just as terrible: For every n, call last and init once each. They're both O(|L|) just as rev.
You could overcome that complexity by carrying out multiple shifts at once. If you know you'll shift one element n times, you might as well shift n elements. Shifting n elements is equivalent to removing |L| - n elements from the front of the list and appending them at the back.
But what if you're asked to shift n elements where n > |L|? Then len - n is negative and both List.drop and List.take will fail. You could fix that by concluding that any full shift of |L| elements has no effect on the result and suffice with n (mod |L|). And what if n < 0?
fun multcshift ([], _) = raise Empty
| multcshift (L, 0) = L
| multcshift (L, n) =
let val len = List.length L
in List.drop (L, len - n mod len) #
List.take (L, len - n mod len) end
There are quite a few corner cases worth testing:
val test_zero = (multcshift ([1,2,3], 0) = [1,2,3])
val test_empty = (multcshift ([], 5); false) handle Empty => true | _ => false
val test_zero_empty = (multcshift ([], 0); false) handle Empty => true | _ => false
val test_negative = (multcshift ([1,2,3,4], ~1) = [2,3,4,1])
val test_nonempty = (multcshift ([1,2,3,4], 3) = [2,3,4,1])
val test_identity = (multcshift ([1,2,3,4], 4) = [1,2,3,4])
val test_large_n = (multcshift [1,2,3,4], 5) = [4,1,2,3])
val test_larger_n = (multcshift [1,2,3,4], 10) = [3,4,1,2])