Is there a function in SML that adds two tuples of equal lengthes like (3,1,2) and (4,3,1) and returns (7,4,3)?
Thank You
No, there is no such function.
There also is no way to write one yourself without hard-coding the length, i.e. you can write a function that takes two tuples of length 2 or a function that takes two tuples of length 3, but it's not possible to write one that takes two tuples of arbitrary (but equal) length. SML's type system simply does not allow you to abstract over a tuple's length like that.
For a specific length, you can, of course, easily define it yourself:
fun addPairs (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)
Related
I'm planning to write am map function which essentially takes in a variable and a list and returns a list.
I've tried to use standard map but from what I've seen it's in the format "map function list" when here I'm trying to pass in another argument which is another point.
data Point = {xCoord :: Int,
yCoord :: Int}
movePoint :: Point -> Point -> Point
movePoint (Point x y) (Point xMove yMove)
= Point (x + xMove) (y + yMove)
// Add a "vector" to a list of points
movePoints :: [Point] -> Point -> [Point]
movePoints = error "Not yet"
For example, if I have a vector for example (2,2) and I have a list of Points such as [(-2,1),(0,0), (5,4) etc.] I want to use map to add (2,2) to all the Points in the list and return a list of points, I'm not sure how to do it. I'm a newbie when it comes to Haskell so any tips would be great.
Partially apply the movePoint function (i.e., call it with fewer arguments than it needs), like this:
movePoints pts vec = map (movePoint vec) pts
Doing so creates a new function that only needs one argument, the one that you didn't provide the first time. This is known as currying.
If I have a list of floats:
let float_list = [1.5,2.5,3.5]
I'm looking to extract a number from this list similar to:
List.nth float_list 2
However what is returned is type float * float and not 3.5. List.nth only seems to return integers from an integer list and I can't seem to find a function in https://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html to return the nth element of any list other than an integer list.
Would anyone be able to help with this?
Your float_list isn't a list of floats, it's a list of float * float * float tuples and it only contains one such tuple. So in addition to not having the type you want, List.nth float_list 2 will actually cause an exception at run time because 2 is not a valid index for that list.
You want [1.5; 2.5; 3.5], which is actually a list of floats. With that list List.nth will work exactly as you want.
List literals in OCaml use ; to separate items. , is used to separate items in tuples. So the type of float_list is actually (float * float * float) list, and it contains only a single element.
I've been trying to solve the following problem for a while now, but can't seem to find the right solution.
Lets say there is a function test(X,Y,Z) such that X is a single pair of numbers, Y is a list of pairs, and Z is the resulting list of transitive pairs.
For example:
test((1,5), [(7,3),(5,2),(5,9)], Z).
Z = [(1,2),(1,9)]
(because of transitivity 1->5->2 and 1->5->9)
So far I've managed to create the following code:
test(_,[],_):- false.
test((X1,C),[(C,Y2)|_],(X1,Y2)).
test((X1,X2),[_|YT],Result) :- test((X1,X2),YT,Result).
It returns each individual result pair like so:
Z = (1, 2) ;
Z = (1, 9) ;
But I can't seem to return them all into a single list like in the example above:
Z = [(1,2),(1,9)]
Any help would be greatly appreciated.
I think the problem is that you're not building the list of transitive pairs. You're just returning a single pair as the third argument of test/3.
Here's one possible solution:
I made a predicate to handle comparing pairs and describing their transitive marriage, so that i didn't have to juggle those tuples in the subsequent rules:
transit((X,T), (T,Y), (X,Y)).
Then it's just a matter of standard list processing with recursive predicates:
t(_, [], []).
t(X, [T|ToTransit], [Y|Transited]) :-
transit(X,T,Y),
t(X,ToTransit,Transited).
t(X, [T|ToTransit], Transited) :-
\+ transit(X,T,_),
t(X,ToTransit, Transited).
Of course, once you have a predicate like transit/3 that defines the relation, you can also do something like
findall( TP,
( member(T, [(2,2), (2,5), (1,5)]), transit((1,2), T, TP) ),
Tps).
map takes a function and a list and applies the function to every element of the list. e.g.,
(map f [x1 x2 x3])
;= [(f x1) (f x2) (f x3)]
Mathematically, a list is a partial function from the natural numbers ℕ. If x : ℕ → X is some list, and f : X → Y is some function, then map takes the pair (f, x) to the list f○x : ℕ → Y. Therefore, map and comp return the same value, at least in the simple case.
However, when we apply map with more than one argument, there's something more complex going on. Consider the example:
(map f [x1 x2 x3] [y1 y2 y3])
;= [(f x1 y1) (f x2 y2) (f x3 y3)]
Here, we have two lists x : ℕ → X and y : ℕ → Y with the same domain, and a function of type f : X → (Y → Z). In order to evaluate on the tuple (f, x, y), map has to do some more work behind the scenes.
First, map constructs the diagonal product list diag(x, y) : ℕ → X × Y, which is defined by diag(x, y)(n) = (x(n), y(n)).
Second, map uncurries the function to curry-1(f) : X × Y → Z. Finally, map composes these operations to get curry-1(f) ○ diag(x, y) : ℕ → Z.
My question is: does this pattern generalize? Namely, suppose that we have three lists x : ℕ → X, y : ℕ → Y and z : ℕ → Z, and a function f : X → (Y → (Z → W))). Does map send the tuple (f, x, y, z) to the list curry-2(f) ○ diag(x, y, z) : ℕ → W?
It seems that the question title has little to do with the question actually asked in the body; I'll try to address both issues.
The Clojure side
As evidenced by examples like (map inc [1 2 3]) and (comp inc [1 2 3]) -- both of which, incidentally, make perfect sense in Clojure -- the Clojure functions map and comp operate completely differently even in the one sequence case. map simply does not treat its sequence arguments as functions in the software sense of callable objects, whereas comp treats all of its arguments in this way; map returns a compound datum, whereas comp does not; the value returned by comp is callable as a function, whereas map's returns values are not; etc.
(Other functional languages similarly have separate "map" and "compose" higher-order functions; in Haskell, these are map (and the more general fmap) and (.).)
Notably, map performs no actual in-memory tupling-up of arguments to its input function and does not apply any deschönfinkelizing / uncurrying transformation to the input function.
The mathematical side
The pattern does of course generalize fine, though it's worth keeping in mind that what's a function of what etc. -- under the hood of the model, as it were -- depends on the choice of representation which tends to be arbitrary. Finite sequences can be represented perfectly well as (total) functions with finite ordinals as domains, or as Kuratowski tuples, or in the way which you describe where you don't care about your lists not necessarily being "gapless" etc. Depending on the representational choices, the concept of natural numbers might not enter the picture at all, the objects representing lists may or may not look like functions whose codomain is a superset of the set of the list's entries etc.
I don't know if it helps, but:
Clojure doesn't have currying, like Haskell. It does have partial function application, but it's not the same as currying.
Clojure's map is more like zipWith, zipWith3, etc in Haskell
Technically yes, map could be viewed as composing functions like this, though in practice it introduces some overhead that comp does not.
map produces a lazy sequence that will compute a sequence when the result is finally read. So it it returns a sequence not strictly the result your type expression implies. It also adds the overhead of sequences and changes the evaluation order because it is lazy and chunked.
How can I calculate the length of a list
?- size_sub([[b,a,g], [9,3,7,4], [6]], X).
X = [3, 4, 1].
?- size_sub([[c,g,e,w], [7]], X).
X = [4, 1].
?- size_sub([], X).
X = [].
Ok you need to start with the base case which is the last answer
so size_sub([],X). is true if X=[] so first you write that as a rule.
size_sub([],[]).
Then you need to do the inductive step a list that is one longer than the previous. I am going to assume that you have a size/2 function for determining the size of a single list (if not please comment).
So the inductive step is going to operate on the length of the first parameter so N->N+1. We would represent this by striping off the head of the list syntax will be [H|T] now the second parameter (your answer) is going to be the length of H with the result of calling size_sub on T. As we cannot specify rules in the parameters in the header we will use N to represent the length of H and T2 to represent the result of size_sub on T.
So the first part of the rule becomes size_sub([H|T],[N|T2]):-
now we follow it with the predicates that will assert the values for N and T2.
size(H,N),
size_sub(T,T2).
putting that all together you get
size_sub([],[]).
size_sub([H|T],[N|T2]):-
size(H,N),
size_sub(T,T2).
size/2 is a far simpler case and following the same process of base + inductive you should be able to create the rules for it. Please comment if you need further help.
** EDIT - Request for size/2 definition **
To define size/2
Start with the base case, the empty list has a size of 0.
size([],0).
Now the inductive step. The size of list of length(N+1) is the size of a list of length(N). So lets define our list as [_|T] I've defined the list using _ to represent the head because we never use it so we can just use the anonymous variable. Lets use N to represent the length of T, and M to be N+1.
so
size([_|T],M):-
now lets define N
size(T,N),
and finally assert that M is equal to N + 1
M is N+1.
so putting everything together
size([],0).
size([_|T],N):-
size(T,M),
N is M+1.
size_sub([],[]).
size_sub([H|T],[N|T2]):-
size(H,N),
size_sub(T,T2).
To map length/2 over a list of lists, we can use the meta-predicate maplist/3 like this:
size_sub(Xss,Ls):-
maplist(length,Xss,Ls).