Parenthesis in currying and type declaration - functional-programming

I'm having a hard time understanding notation used for currying. Maybe it means I have a deeper confusion regarding the subject but I don't think so.
I understand how something like...
add (x,y) = x + y can have a type (int, int) -> int.
It also makes sense the curried form would look like this:
add x y = x + y with type int -> int -> int, aka type int -> (int-> int).
I would like to know what the parenthesis mean in that last example. Is the first int x, the second int y, and the last int the output? What would a function like this look like?
(int -> int) -> int
I know something isn't clicking and it's very frustrating.

Types of the form a -> b really just mean
function taking a value of type a and returning a value of type b
And from there on it's just repeated application for larger (multiple arrows) types, much like 1 + 2 + 3 + 4 isn't all that different from 1 + 2.
One potential stumbling stone is that either of these values can be a function itself. Your interpretation of the curried type is correct, but note that add x is a valid expression on its own, and gives another function (one which only needs one argument before returning an int).
As for the second type: Just like int -> (int -> int) is the type
take an int and return a function int -> int"
the type (int -> int) -> int means
take a function int -> int and return an int
It's a higher-order function, a function which accepts a function as argument.
One not-entirely-useless example would be the function sum0To100 f = sum (map f [0 .. 100]) (or equivalent functions for any other range). For example, sum0To100 fib is the sum of the first 100 Fibonacci numbers.

Related

Schroders Big number sequence

I am implementing a recursive program to calculate the certain values in the Schroder sequence, and I'm having two problems:
I need to calculate the number of calls in the program;
Past a certain number, the program will generate incorrect values (I think it's because the number is too big);
Here is the code:
let rec schroder n =
if n <= 0 then 1
else if n = 1 then 2
else 3 * schroder (n-1) + sum n 1
and sum n k =
if (k > n-2) then 0
else schroder k * schroder (n-k-1) + sum n (k+1)
When I try to return tuples (1.), the function sum stops working because it's trying to return int when it has type int * int;
Regarding 2., when I do schroder 15 it returns:
-357364258
when it should be returning
3937603038.
EDIT:
firstly thanks for the tips, secondly after some hours of deep struggle, i manage to create the function, now my problem is that i'm struggling to install zarith. I think I got it installed, but ..
in terminal when i do ocamlc -I +zarith test.ml i get an error saying Required module 'Z' is unavailable.
in utop after doing #load "zarith.cma";; and #install_printer Z.pp_print;; i can compile, run the function and it works. However i'm trying to implement a Scanf.scanf so that i can print different values of the sequence. With this being said whenever i try to run the scanf, i dont get a chance to write any number as i get a message saying that '\\n' is not a decimal digit.
With this being said i will most probably also have problems with printing the value, because i dont think that i'm going to be able to print such a big number with a %d. The let r1,c1 = in the following code, is a example of what i'm talking about.
Here's what i'm using :
(function)
..
let v1, v2 = Scanf.scanf "%d %d" (fun v1 v2-> v1,v2);;
let r1,c1 = schroder_a (Big_int_Z.of_int v1) in
Printf.printf "%d %d\n" (Big_int_Z.int_of_big_int r1) (Big_int_Z.int_of_big_int c1);
let r2,c2 = schroder_a v2 in
Printf.printf "%d %d\n" r2 c2;
P.S. 'r1' & 'r2' stands for result, and 'c1' and 'c2' stands for the number of calls of schroder's recursive function.
P.S.S. the prints are written differently because i was just testing, but i cant even pass through the scanf so..
This is the third time I've seen this problem here on StackOverflow, so I assume it's some kind of school assignment. As such, I'm just going to make some comments.
OCaml doesn't have a function named sum built in. If it's a function you've written yourself, the obvious suggestion would be to rewrite it so that it knows how to add up the tuples that you want to return. That would be one approach, at any rate.
It's true, ints in OCaml are subject to overflow. If you want to calculate larger values you need to use a "big number" package. The one to use with a modern OCaml is Zarith (I have linked to the description on ocaml.org).
However, none of the other people solving this assignment have mentioned overflow as a problem. It could be that you're OK if you just solve for representable OCaml int values.
3937603038 is larger than what a 32-bit int can hold, and will therefore overflow. You can fix this by using int64 instead (until you overflow that too). You'll have to use int64 literals, using the L suffix, and operations from the Int64 module. Here's your code converted to compute the value as an int64:
let rec schroder n =
if n <= 0 then 1L
else if n = 1 then 2L
else Int64.add (Int64.mul 3L (schroder (n-1))) (sum n 1)
and sum n k =
if (k > n-2) then 0L
else Int64.add (Int64.mul (schroder k) (schroder (n-k-1))) (sum n (k+1))
I need to calculate the number of calls in the program;
...
the function 'sum' stops working because it's trying to return 'int' when it has type 'int * int'
Make sure that you have updated all the recursive calls to shroder. Remember it is now returning a pair not a number, so you can't, for example, just to add it and you need to unpack the pair first. E.g.,
...
else
let r,i = schroder (n-1) (i+1) in
3 * r + sum n 1 and ...
and so on.
Past a certain number, the program will generate incorrect values (I think it's because the number is too big);
You need to use an arbitrary-precision numbers, e.g., zarith

How do I check if the path from a node to another has a depth equal to a given one in a graph in OCaml?

First of all, I'm sorry for how I wrote my question.
Anyway, I'm trying to write a function in OCaml that, given a graph, a max depth, a starting node, and another node, returns the list of the nodes that make the path but only if the depth of it is equal to the given one. However, I can't implement the depth part.
This is what I did:
let m = [(1, 2, "A"); (2, 3, "A");
(3, 1, "A"); (2, 4, "B");
(4, 5, "B"); (4, 6, "C");
(6, 3, "C"); (5, 7, "D");
(6, 7, "D")]
let rec vicini n = function
[] -> []
| (x, y, _)::rest ->
if x = n then y :: vicini n rest
else if y = n then x :: vicini n rest
else vicini n rest
exception NotFound
let raggiungi m maxc start goal =
let rec from_node visited n =
if List.mem n visited then raise NotFound
else if n = goal then [n]
else n :: from_list (n :: visited) (vicini n m)
and from_list visited = function
[] -> raise NotFound
| n::rest ->
try from_node visited n
with NotFound -> from_list visited rest
in start :: from_list [] (vicini start m)
I know I have to add another parameter that increases with every recursion and then check if its the same as the given one, but I don't know where
I am not going to solve your homework, but I will try to teach you how to use recursion.
In programming, especially functional programming, we use recursion to express iteration. In an iterative procedure, there are things that change with each step and things that remain the same on each step. An iteration is well-founded if it has an end, i.e., at some point in time, the thing that changes reaches its foundation and stops. The thing that changes on each step, is usually called an induction variable as the tribute to the mathematical induction. In mathematical induction, we take a complex construct and deconstruct it step by step. For example, consider how we induct over a list to understand its length,
let rec length xs = match xs with
| [] -> 0
| _ :: xs -> 1 + length xs
Since the list is defined inductively, i.e., a list is either an empty list [] or a pair of an element x and a list, x :: list called a cons. So to discover how many elements in the list we follow its recursive definition, and deconstruct it step by step until we reach the foundation, which is, in our case, the empty list.
In the example above, our inductive variable was the list and we didn't introduce any variable that will represent the length itself. We used the program stack to store the length of the list, which resulted in an algorithm that consumes memory equivalent to the size of the list to compute its length. Doesn't sound very efficient, so we can try to devise another version that will use a variable passed to the function, which will track the length of the list, let's call it cnt,
let rec length cnt xs = match xs with
| [] -> cnt
| _ :: xs -> length (cnt+1) xs
Notice, how on each step we deconstruct the list and increment the cnt variable. Here, call to the length (cnt+1) xs is the same as you would see in an English-language explanation of an algorithm that will state something like, increment cnt by one, set xs to the tail xs and goto step 1. The only difference with the imperative implementation is that we use arguments of a function and change them on each call, instead of changing them in place.
As the final example, let's devise a function that checks that there's a letter in the first n letters in the word, which is represented as a list of characters. In this function, we have two parameters, both are inductive (note that a natural number is also an inductive type that is defined much like a list, i.e., a number is zero or the successor of a number). Our recursion is also well-founded, in fact, it even has two foundations, the 0 length and the empty list, whatever comes first. It also has a parameter that doesn't change.
let rec has_letter_in_prefix letter length input =
length > 0 && match input with
| [] -> false
| char :: input ->
char = letter || has_letter_in_prefix letter (length-1) input
I hope that this will help you in understanding how to encode iterations with recursion.

Is it possible to write a reference to an object in the dictionary value in Python?

Can I use a value in a dictionary as a reference to an object?
Example:
a = 60
b = 70
dict_a = {'command_1':a,'command_2':b}
print(dict_a)
##{'command_1': 60, 'command_2': 70}
When we change "a" was the next change in the dictionary
b = 50
print(dict_a)
##{'command_1': 60, 'command_2': 50}
Yes, you can, but not this way.
What happens here, is this:
b = 70
# b is now reference to anonymous int object with value of 70
dict_a = {'command_1':a,'command_2':b}
# dict_a['command_2'] now points *to the same int object* as b
b = 50
#b now points to another anonymous int object with value of 50
Bottom line. When doing
b=X
something=b
we are pointing both b and something to X. When we later change b to point to Y, something still points to X. when assigning, look at right side of previous assignment.
One of the things you can do is use some smarter object as dict value, whose internal value can be changed by calling some method in it.
eg. assuming a myint class which extends int:
n=myint(5)
mydict=dict(command_1=n)
n.set_value(8)
This should work as n still references the same object as the one in dict.
I don't have python docs at hand, perhaps you can do this with int object as well, but I doubt it, as int objects are immutable.

Need review of scheduling model logic, suggestions for constraint creation and fixes for syntax errors

I am creating a scheduling model for a blending facility in Mini Zinc. I have asked a similar question earlier but I have since progressed. I will summarize what I think my existing model should do, it would be super helpful if someone could correct any logical or syntax errors I have made. The model currently errors, with several instances of "expecting end of file". It seems way to simplistic in comparison to several other sequence dependent scheduling models I have found. Below you will find the model code commented with my understanding of each line.
Besides an overview of the logic and syntax, I am looking for help with the "missing constraint" in this model, which needs to require that the array of blends [y] contain no more than the declared integer quantity of each blend.
Notable future goals for this model include automatic generation of the blendcost matrix, output the schedule array given a starting day into a 5 column matrix representing weekdays, and showing the blend name as opposed to blend number.
enum Blends = { A, B, C, D, E, F};
%Establish names for each blend and link them to their order number.
int: nb = count([Blends])
%Count the number of blends, plan to use later.
int: qA; %Error: syntax error, unexpected int, expecting end of file
int: qB;
int: qC;
int: qD;
int: qE;
int: qF;
int: sb;
%Call for inputs of the quantity of each of the blends needed, as well as the number/letter of the blend currently in the machine.
int: mc = qA + qB + qC + qD + qE + qF;
%Sum the blend quantities to determine total number of blends
[Blendcost] : [|1,2,2,2,2,2,|1,1,1,1,1,1,|1,1,1,1,1,1,|2,2,2,1,2,2,|1,1,1,1,1,1,|1,1,1,1,1,1,|]; %Error: syntax error, unexpected [|, expecting identifier
%Establishes a blend cost matrix, 6X6 depicting the transition costs from any blend A-F to any other blend A-F
array [Blends] of int: 1..6;
%Is this line needed to establish the link between A/1, B/2, C/3 etc;? Or is that taken care of when Blends is enumerated?
array [0..mc] of var 1..6: y;
%Create an array from 0 to the number of blends with potential values from 1-6, corresponding to the blend numbers.
%Missing constraint: [y] can contain no more than the quantity of each blend declared above, except for the blend declared in the starting blend, which will be allowed that blend quantity + 1
constraint y(0) = sb
%y(0) is set equal to the starting blend Letter/Number Defined earlier, used to determine the first transitionary cost.
array [1..mc] of int: x(i); %Error: syntax error, unexpected array, expecting end of file
%Create an array from 1 to number of blends, which will be filled with the transition costs in response to variations in y
constraint forall(i in x)(x(i) = Blendcost(y(i-1),y(i)))
%For each space in x, x will equal the blend cost value obtained from the previous blend in the y array vs the next blend in the y array
solve minimize sum (x); %Error: syntax error, unexpected solve, expecting end of file
%Solves this model attempting to minimize the sum of the x array, which should be filled with the transition costs.
show(y):
%Print the final array of blend numbers that has minimized blend cost transition.
%Error: unexpected end of file, expecting identifier.
Here is a basic version of your CP-model that runs (assuming some demand q):
enum BLEND = { A, B, C, D, E, F};
array[BLEND] of int: q = [1, 2, 4, 6, 8, 1];
array[BLEND, BLEND] of int: Blendcost =
[|1,2,2,2,2,2|1,1,1,1,1,1|1,1,1,1,1,1|2,2,2,1,2,2|1,1,1,1,1,1|1,1,1,1,1,1|];
int: mc = sum(q);
array[1..mc] of var BLEND: y;
include "global_cardinality.mzn";
constraint global_cardinality(y, BLEND, q);
var int: obj = sum(p in 1..mc-1)(Blendcost[y[p],y[p+1]]) + 1;
array[int] of var opt BLEND: day = [y[p] | p in 1..mc-1, q in 1..max(Blendcost) where q <= Blendcost[y[p],y[p+1]]] ++ [y[mc]];
array[int] of var opt int: wash = [bool2int(q > 1) | p in 1..mc-1, q in 1..max(Blendcost) where q <= Blendcost[y[p],y[p+1]]] ++ [0];
solve minimize obj;
output ["obj=\(obj)\n"] ++
["day=\n"] ++ [
show(day[d]) ++ if fix(wash[d]) > 0 then "W" else "" endif ++ " " ++
if d mod 5 = 0 then "\n" else "" endif | d in 1..length(day)
] ++ ["\nmc=\(mc)\n"] ++ ["y=\(y)\n"] ++ ["wash=\(wash)\n"]
Have a look at https://www.minizinc.org/doc-2.2.3/en/lib-globals.html#counting-constraints for alternative versions of the counting constraint.
For larger instances a MIP-model might show better performance.

What is the upper bound of Integer in Haskell?

I was solving a math problem: want to get the sum of the digits of the number 2^1000.
In Java, the solution is like:
String temp = BigInteger.ONE.shiftLeft(1000).toString();
int sum = 0;
for (int i = 0; i < temp.length(); i++)
sum += temp.charAt(i) - '0';
Then came up a solution in Haskell, like this:
digitSum ::(Integral a) => a -> a
digitSum 0 = 0
digitSum n = (mod n 10) + (digitSum (div n 10))
The whole process is pretty smooth, one point seems interesting, we know integer type can not handle 2 ^ 1000, too big, in Java, it's obvious to use BigInteger and treat the big number to string, but in Haskell, no compiling errors means the 2 ^ 1000 could be passed in directly. Here is the thing, does Haskell transform the number into string internally? I want to make sure what the type is and let the compiler to determine, then I type the following lines in GHCi:
Prelude> let i = 2 ^ 1000
Prelude> i
107150860718626732094842504906000181056140481170553360744375038837035105112493612249319
837881569585812759467291755314682518714528569231404359845775746985748039345677748242309
854210746050623711418779541821530464749835819412673987675591655439460770629145711964776
86542167660429831652624386837205668069376
Prelude> :t i
i :: Integer
Here, I was totally confused, apparently, the number of i is oversized, but the return type of i is still Integer. How could we explain this and what's the upper bound or limit of Integer of Haskell?
In Haskell, Integer is a - theoretically - unbounded integer type. Fixed-width types are Int, Int8, Int16, Int32, Int64 and the corresponding unsigned Word, Word8 etc.
In practice, even Integer is of course bounded, by the available memory for instance, or by the internal representation.
By default, GHC uses the GMP package to represent Integer, and that means the bound is 2^(2^37) or so, since GMP uses a 32-bit integer to store the number of limbs.

Resources