Sub list of a list in taking the second element - list

Suppose I have the following list of tuple [("a", "b"); ("c", "d"); ("e", "f"); ("g", "h"); ("i", "j")]. I would like to create a sub list from that list by taking the second element of each tuple of that list. In other words, I want to obtain ["a"; "d"; "f", "h"].
I tried iter (fun (x,y) -> liste#[y]) old_list;; but I got
Error: This expression has type (string * string) list
but an expression was expected of type unit
Do I have to use a recursive function? Is there a workaround?

The type of List.iter is ('a -> unit) -> 'a list -> unit. In other words, it returns unit, which is the way in OCaml to return nothing (or nothing interesting anyway).
Since you want your function to return a result, you can't use List.iter. Instead, you want to transform each element of a list in some way. The function that does this is List.map.
Here's a function that changes a list of ints into a list of bools according to whether each int is odd or even:
let is_even list = List.map (fun x -> x mod 2 = 0) list
It works like this:
# is_even [3;4;5;6;7];;
- : bool list = [false; true; false; true; false]
You want something like this with a different fun expression.
As a side comment, your result isn't what would usually be called a sublist of the original list. A sublist is a new list containing some of the elements of the old list. You could call it a projection more accurately I think.

Related

F# return list of list lengths

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.

How do I avoid the Value Restriction error when the argument is an empty list?

Some functions in the List module fail when the argument is an empty list. List.rev is an example. The problem is the dreaded Value Restriction.
I met the same problem while trying to define a function that returns a list with all but the last element of a list:
let takeAllButLast (xs: 'a list) =
xs |> List.take (xs.Length - 1)
The function works well with nonempty lists, but a version that would handle empty lists fails:
let takeAllButLast (xs: 'a list) =
if List.isEmpty xs then []
else xs |> List.take (xs.Length - 1)
takeAllButLast []
error FS0030: Value restriction. The value 'it' has been inferred to have generic type
val it : '_a list, etc.
I tried several things: making it an inline function, not specifying a type for the argument, specifying a type for the returned value, making the function depend on a type argument, and using the Option type to obtain an intermediate result later converted to list<'a>. Nothing worked.
For example, this function has the same problem:
let takeAllButLast<'a> (xs: 'a list) =
let empty : 'a list = []
if List.isEmpty xs then empty
else xs |> List.take (xs.Length - 1)
A similar question was asked before in SO: F# value restriction in empty list but the only answer also fails when the argument is an empty list.
Is there a way to write a function that handles both empty and nonempty lists?
Note: The question is not specific to a function that returns all but the last element of a list.
The function itself is completely fine. The function does not "fail".
You do not need to modify the body of the function. It is correct.
The problem is only with the way you're trying to call the function: takeAllButLast []. Here, the compiler doesn't know what type the result should have. Should it be string list? Or should it be int list? Maybe bool list? No way for the compiler to know. So it complains.
In order to compile such call, you need to help the compiler out: just tell it what type you expect to get. This can be done either from context:
// The compiler gleans the result type from the type of receiving variable `l`
let l: int list = takeAllButLast []
// Here, the compiler gleans the type from what function `f` expects:
let f (l: int list) = printfn "The list: %A" l
f (takeAllButLast [])
Or you can declare the type of the call expression directly:
(takeAllButLast [] : int list)
Or you can declare the type of the function, and then call it:
(takeAllButLast : int list -> int list) []
You can also do this in two steps:
let takeAllButLast_Int : int list -> int list = takeAllButLast
takeAllButLast_Int []
In every case the principle is the same: the compiler needs to know from somewhere what type you expect here.
Alternatively, you can give it a name and make that name generic:
let x<'a> = takeAllButLast [] : 'a list
Such value can be accessed as if it was a regular value, but behind the scenes it is compiled as a parameterless generic function, which means that every access to it will result in execution of its body. This is how List.empty and similar "generic values" are implemented in the standard library.
But of course, if you try to evaluate such value in F# interactive, you'll face the very same gotcha again - the type must be known - and you'll have to work around it anyway:
> x // value restriction
> (x : int list) // works

Strong union of two lists

I've defined functions:
fun concaten(x,y) =
if (x = [])
then y
else hd(x) :: concaten(tl(x),y);
as well as:
fun existsin(x,L) =
if (L=[])
then false
else if (x = hd(L))
then true
else existsin(x,tl(L));
and am now trying to define a function of type (((list * list) -> list) -> list) that looks vaguely like the following:
fun strongunion(x,y) =
val xy = concaten(x,y);
if xy=[]
then []
if (existsin(hd(xy),tl(xy)) andalso x!= [])
then strongunion(tl(x),y)
else if (existsin(hd(xy),tl(xy)) andalso x = [])
then strongunion(x,tl(y))
else if (x != [])
then hd(xy) :: strongunion(tl(x),y)
else hd(xy) :: strongunion(x,tl(y));
which takes the "strong" union of two lists, i.e. it combats faulty inputs (lists with element duplicates). This code is, of course, syntactically invalid, but the reason I included it was to show what such a function would look like in an imperative language.
The way I started going about doing this was to first concatenate the lists, then remove duplicated elements from that concatenation (well, technically I am adding non-duplicates to an empty list, but these two operations are consequentially equivalent). To do this, I figured I would design the function to take two lists (type list*list), transform them into their concatenation (type list), then do the duplicate removal (type list), which would be of type (((list*list) -> list) -> list).
My issue is that I have no idea how to do this in SML. I'm required to use SML for a class for which I'm a TA, otherwise I wouldn't bother with it, and instead use something like Haskell. If someone can show me how to construct such higher-order functions, I should be able to take care of the rest, but I just haven't come across such constructions in my reading of SML literature.
I'm a bit unsure if strong union means anything other than just union. If you assume that a function union : ''a list * ''a list -> ''a list takes two lists of elements without duplicates as inputs, then you can make it produce the unions without duplicates by conditionally inserting each element from the one list into the other:
(* insert a single element into a list *)
fun insert (x, []) = [x]
| insert (x, xs as (y::ys)) =
if x = y
then xs
else y::insert(x, ys)
(* using manual recursion *)
fun union ([], ys) = ys
| union (x::xs, ys) = union (xs, insert (x, ys))
(* using higher-order list-combinator *)
fun union (xs, ys) = foldl insert ys xs
Trying this:
- val demo = union ([1,2,3,4], [3,4,5,6]);
> val demo = [3, 4, 5, 6, 1, 2] : int list
Note, however, that union wouldn't be a higher-order function, since it doesn't take functions as input or return functions. You could use a slightly stretched definition and make it curried, i.e. union : ''a list -> ''a list -> ''a list, and say that it's higher-order when partially applying it to only one list, e.g. like union [1,2,3]. It wouldn't even be fully polymorphic since it accepts only lists of types that can be compared (e.g. you can't take the union of two sets of functions).

How to aggregate over many lists in F#

In F# at some point I have many lists (the actual number of them differs for input data) and I want to make an aggregation over all those lists (let say addition for simplification). So what I want to achieve is the same what List.map2 or List.map3 does but for bigger number of lists.
How can I approach it? I was wondering if this is possible to do with List.scan?
You can use List.reduce and do something like this:
> let lists = [[1;2;3]; [1;2;3]; [1;2;3]]
val lists : int list list = (...)
> lists |> List.reduce (List.map2 (+));;
val it : int list = [3; 6; 9]
What does this do?
List.reduce takes a list of values (here the value is int list) and it aggregates them into a single value using a function that says how to merge two values. So in this case, we need to give it a function int list -> int list -> int list and it will call it on the first and the second list, then on the result and the third list (and so on).
The argument List.map2 (+) is a function of the right type - it takes two lists and performs pairwise sum of the two lists. This is really just a shortcut for writing something like:
lists |> List.reduce (fun list1 list2 ->
List.map2 (fun a b -> a + b) list1 list2)

creat a tuple by removing first element from another tuple in ML

using ML as a programming language we have list and tuple, in the case of lists we can form a list from another list by removing or appending elements from and to the original list, for example if we have:
val x = [7,8,9] : int list
in REPL we can do some operations like the following:
- hd x;
val it = 7 : int
- tl x;
val it = [8,9] : int list
now if we have a tuple lets say:
val y = (7,8,9) :int*int*int
now the question is that , can we have a smaller tuple by removing the first element from the original tuple ? in other words , how to remove (#1 y) and have new tuple (8,9) in a similar way that we do it in the case of list.
Thanks.
Tuples are very different from lists. With lists, size need not be known at compile time, but with tuples, not only should the number of elements be known at compile time, the type of each element is independent of the others.
Take the type signature of tl:
- tl;
val it = fn : 'a list -> 'a list
It is 'a list -> 'a list - in other words tl takes a list of 'a and returns another one. Why don't we have one for tuples as well? Assume we wanted something like
y = (1,2,3);
tail y; (* returns (2,3) *)
Why does this not make sense? Think of the type signature of tail. What would it be?
In this case, it would clearly be
'a * 'b * 'c -> 'b * 'c
Takes product of an 'a, a 'b and a 'c and returns a product of
a 'b and a 'c. In ML, all functions defined must have a statically determined
type signature. It would be impossible to have a tail function for tuples that
handles all possible tuple sizes, because each tuple size is essentially a different type.
'a list
Can be the type of many kinds of lists: [1,2,3,4], or ["A", "short", "sentence"], or
[true, false, false, true, false]. In all these cases, the value of the type
variable 'a is bound to a different type. (int, string, and bool). And 'a list can be a list of any size.
But take tuples:
(1, true, "yes"); (* (int * bool * string) *)
("two", 2) (* (string, int) *)
("ok", "two", 2) (* (string, string, int) *)
Unlike list, these are all of different types. So while the type signature of all lists is simple ('a list), there is no 'common type' for all tuples - a 2-tuple has a different type from a 3-tuple.
So you'll have to do this instead:
y = (7, 8, 9);
(a, b, c) = y;
and a is your head and you can re-create the tail with (b,c).
Or create your own tail:
fun tail (a,b,c) = (b, c)
This also gives us an intuitive understanding as to why such a function would not make sense: If is impossible to define a single tail for use across all tuple types:
fun tail (a,b) = (b)
| tail (a,b,c) = (b, c) (* won't compile *)
You can also use the # shorthand to get at certain elements of the tuple:
#1 y; (* returns 7 *)
But note that #1 is not a function but a compile time shorthand.
Lists and tuples are immutable so there is no such thing like removing elements from them.
You can construct a new tuple by decomposing the original tuple. In SML, the preferred way is to use pattern matching:
fun getLastTwo (x, y, z) = (y, z)
If you like #n functions, you can use them as well:
val xyz = (7, 8, 9)
val yz = (#2 xyz, #3 xyz) (* (8, 9) *)