In sml, we define lists of integers or strings as arguments by l::ls which helps us to define lists of arbitrary length and then we can compare with = or > or <. How can we denote tuples in similar manner?
e.g.
I can write,
fun delete(x,l::ls)=if x=l then delete(x,ls) else l::delete(x,ls)
how can I write similarly for tuples?
Note, I even need to compare the individual elements of the tuple: i.e. (a1,b1)>(a2,b2) if b1>b2 so some sortcut that can merely delete like above will not be sufficient.
Tons of Thank You.
You can do pattern matching directly on tuples using the usual form (x, y).
Your delete function works on any 'a list so it is correct for lists of tuples as well. Here is an example which filters a list based on the first values in tuples:
fun deleteByFirst(x0, []) = []
| deleteByFirst(x0, (x, y)::ls) =
if x = x0
then deleteByFirst(x0, ls)
else (x, y)::deleteByFirst(x0, ls)
Related
I am to use combinators and no for/while loops, recursion or defined library functions from F#'s List module, except constructors :: and []
Ideally I want to implement map
I am trying to write a function called llength that returns the list of the lengths of the sublists. For example llength [[1;2;3];[1;2];[1;2;3]] should return [3;2,3]. I also have function length that returns the length of a list.
let Tuple f = fun a b -> f (a, b)
let length l : int =
List.fold (Tuple (fst >> (+) 1)) 0 l
currently have
let llength l : int list =
List.map (length inner list) list
Not sure how I should try accessing my sublists with my restraints and should I use my other method on each sublist? any help is greatly appreciated, thanks!
Since this is homework, I don't want to just give you a fully coded solution, but here are some hints:
First, since fold is allowed you could implement map via fold. The folding function would take the list accumulated "so far" and prepend the next element transformed with mapping function. The result will come out reversed though (fold traverses forward, but you prepend at every step), so perhaps that wouldn't work for you if you're not allowed List.rev.
Second - the most obvious, fundamental way: naked recursion. Here's the way to think about it: (1) when the argument is an empty list, result should be an empty list; (2) when the argument is a non-empty list, the result should be length of the argument's head prepended to the list of lengths of the argument's tail, which can be calculated recursively. Try to write that down in F#, and there will be your solution.
Since you can use some functions that basically have a loop (fold, filter ...), there might be some "cheated & dirty" ways to implement map. For example, via filter:
let mymap f xs =
let mutable result = []
xs
|> List.filter (fun x ->
result <- f x :: result
true)
|> ignore
result |> List.rev
Note that List.rev is required as explained in the other answer.
I am writing a function that will take a list of list and merge it into sorted pairs of list. For example [[1],[9],[8],[7],[4],[5],[6]] would return [[1,9],[7,8],[4,5],[6]]. This is my first attempt at SML. I keep getting this error: operator and operand don't agree [overload conflict].
fun mergePass[] = []
| mergePass(x::[]) = x::[]
| mergePass(x::y::Z) =
if x<y
then (x # y)::mergePass(Z)
else (y # x)::mergePass(Z);
Edit: If mergePass is called on [[1,9],[7,8],[4,5],[6]] I will need it to return [[1,7,8,9],[4,5,6]].
This merge function takes two sorted lists
fun merge([],y) = y
| merge(x,[]) = x
| merge(a::x,b::y) =
if a < b then a::merge(x,b::y)
else b::merge(a::x,y);
You seem reasonably close. A few hints/remarks:
1) Aesthetically, using nil in one line and [] in others seems odd. Either use all nil or use all []
2) Since the input are lists of lists, in x::y::z, the identifiers x and y would be lists of integers, rather than individual integers. Thus, x<y wouldn't make sense. You can't compare lists of integers using <.
3) Your problem description strongly suggests that the inner-lists are all 1-element lists. Thus you could use the pattern [x]::[y]::z to allow you to compare x and y. In this case, x#y could be replaced by [x,y]
4) If the inner lists are allowed to be of arbitrary size, then your code needs major revision and would probably require a full-fledged sort function to sort the result of concatenating pairs of inner lists. Also, in this case, the single list in the one inner list case should probably be sorted.
5) You have a typo: mergeP isn't mergePass.
On Edit:
If the sublists are each sorted (and the name of the overall function perhaps suggests this) then you need a function called e.g. merge which will take two sorted lists and combine them into a single sorted list. If this is for a class and you have already seen a merge function as an example (perhaps in a discussion of merge-sort) -- just use that. Otherwise you will have to write your own before you write this function. Once you have the merge function, skip the part of comparing x and y and instead have something as simple as:
| mergePass (xs::ys::zss) = (merge xs ys) :: mergePass zss
If the sublists are not merged, then you will need a full-fledged sort in which case you would use something like:
| mergePass (xs::ys::zss) = sort(xs # ys) :: mergePass zss
So I'm trying to write some minimal code to put two lists of strings together, and to do this I thought it was best to use the haskell map function.
Essentially I want to be able to do adders ["1","2"] ["3","4"] = ["1","2","3","4"]
So I have a function called adder, which takes a list, then adds a string to that list and returns the new list. Then I have a function called adders which replicates the adder function, but adds a list of strings instead of just one string, however at the moment it produces multiple lists instead of one list.
I thought
adder :: [String] -> String -> [String]
adder y x = y ++ [x]
adders y x = map (adder y) x
would work, but this just gives a list of two lists
[["1","2","3"],[["1","2","4"]]
How is the best way to go about this?
I thought it was best to use the haskell map function
No. map f applies f to every element of your list. But you don't want to change the elements at all, you want to change the list itself. That, however, is out of scope of the things that are possible with map. map cannot add more elements, neither can it remove some.
If you want to concatenate two lists, simply use ++:
adders :: [a] -> [a] -> [a]
adders x y = x ++ y
I'm coding in haskell and want to know how find a certain element in mutiple list.
Here an example let say:
x = [(1,2,3,4,5),
(3,4,5,6,6),
(5,6,2,1,1),
(1,2,5,6,2)];
Let say I want to find the 3rd element of each list.
So the program will print out 4,6,1,6
I know about the !! but when I do something like x !! 3, it prints out the third row(1,2,5,6,2).
I want it so it print out the 3rd element of each list.
What you've provided is not actually a list of lists, but a list of tuples. Tuples have a special type based on the number and type of their elements, so the type of your x above is [(Int,Int,Int,Int,Int)].
Unlike lists, which allow us to extract values by index with the !! operator (ex. [1,2,3] !! 1 = 2), in order to extract specific values from a tuple we must pattern match the entire tuple, giving some name to the value we wish to extract and using it in our return value. To extract the fourth value from a tuple of holding 5 values, we could write a function like this:
f (a,b,c,d,e) = d
Or, as an anonymous function (because, if we are only going to use it when mapping over the list, it's nice to not bother assigning it a name):
(\(a,b,c,d,e) -> d)
Since we only care about the fourth value, we can choose to discard all others (you said third but meant index 3 -> 4th term above?):
(\(_,_,_,x,_) -> x)
Now we have a list of such tuples, and we'll want to apply it to each. We can do this with map, which will apply the function to each and return a list of the third value from each tuple:
f xs = map (\(_,_,_,x,_) -> x) xs
Or, with eta-reduction:
f = map (\(_,_,_,x,_) -> x)
Example usage:
gchi>> f [(1,2,3,4,5),(3,4,5,6,6),(5,6,2,1,1),(1,2,5,6,2)]
[4,6,1,6]
So I've got this list of lists of strings:
[["##","**","##"],["##","*%","##"]]
What I want to do is transform each inner list into a single string like this:
["##**##","##*%##"]
Resulting in a list of strings.
I've tried various combinations of map, foldr, and anonymous functions, but I can't for the life of me figure out how to achieve my desired result.
There is a function concat : string list -> string in the String structure in the Basis Library, which happens to be at the top level. Therefore, you can define your function:
val concatEach = map concat
It is going to have type string list list -> string list, which I guess is what you are looking for.
If you want to define your own concat function, you can do it this way:
val myConcat = foldr (op ^) ""
Or, without using the op keyword:
val myConcat' = foldr (fn (x, y) => x ^ y) ""