Haskell swap nested list - list

I have this function:
swap [] = []
swap [a] = [a]
swap a = last a : (init . tail $ a) ++ [head a]
If I use this on a list with lists, it just turns each list around, and not the elements in each list. What am I missing here?

swap takes a list of things, and exchanges its first element for its last. Since there is nothing in there about looking inside of those elements at all, it definitely will not modify any of the elements inside of a list.
But if you have a list of things, and you want to perform some modification of each item in the list, there is a function for that already: map. And the modification you want to perform is swap, so let's see how the types line up.
map :: ( a -> b) -> [a] -> [b]
swap :: [a] -> [a]
map swap :: [[a]] -> [[a]]
So map swap takes a list of lists, and swaps each of those sublists, without changing the order of the "larger" list at all.

Related

Apppend a list in a list of list - Haskell

I'm trying to do a function in haskell. The purpose of the function is to add a list to an existing list of list.
[Int] -> [[Int]] -> [[Int]]
I wish it would work like :
[1] -> [[2],[3]] -> [[2],[3],[1]]
I would like to know how I can proceed to do that. There is an existing included function to do that?
You can wrap the element [1] in a singleton list, and then append the two lists with (++) :: [a] -> [a] -> [a]. So you can implement such function with:
addlast :: a -> [a] -> [a]
addlast x ys = ys ++ [x]
The (++) function however will usually take linear time in the number of elements of the left operand (so ys), which makes it computationally expensive. Therefore it is usually better if order does not matter to prepend to a list.
In the extra package [Hackage], you can make use of snoc :: [a] -> a -> [a]. In that case, this is thus a "flipped" version of snoc:
import Data.List.Extra(snoc)
addlast :: a -> [a] -> [a]
addlast = flip snoc

Concatenation in Haskell and confusion with AList ([a] -> [a])

I have a project where we are improving the speed of concatenating a list in Haskell.
I'm new to Haskell and confused about AList ([a] -> [a]) Specifically how to convert my AppendedList to a regular List. Any help would be appreciated.
newtype AppendedList a = AList ([a] -> [a])
-- List[5] is represented as AList (\x -> 5:x)
-- This function takes an argument and returns the AppendedList for that
single :: a -> AppendedList a
single m = AList (\x -> m : x)
-- converts AppendedList to regular List
toList :: AppendedList a -> [a]
toList = ???
The toughest part is to not give you the answer directly :)
If you remember how lists are constructed in Haskell: [1, 2, 3] = 1 : 2 : 3 : [], with [] being the empty list.
Now let's "follow the types" (we also call this thought process TDD for Type Driven Development) and see what you have at hand:
toList :: AppendedList a -> [a]
toList (AList listFunction) = ???
and listFunction has the type [a] -> [a]. So you need to provide it a polymorphic list (i.e. a list of any type) so that it gives you back a list.
What is the only list of any type you know of? Pass this list to listFunction and everything will compile, which is a good indicator that it's probably right :D
I hope that helps without providing the plain answer (the goal is for you to learn!).
AppendedList a is a type.
AList f is a datum of that type, with some function f :: [a] -> [a] "inside it".
f is a function from lists to lists with the same type of elements.
We can call it with some_list :: [a] to get resulting_list :: [a]:
f :: [a] -> [a]
some_list :: [a]
-------------------------
f some_list :: [a]
resulting_list :: [a]
resulting_list = f some_list
We can use resulting_list as some_list, too, i.e..
resulting_list = f resulting_list
because it has the same type, that fits f's expectations (and because of Haskell's laziness). Thus
toList (...) = let { ... = ... }
in ...
is one possible definition. With it,
take 2 (toList (single 5))
would return [5,5].
edit: Certainly [5,5] is not the list containing a single 5. Moreover, take 4 ... would return [5,5,5,5], so our representation contains any amount of fives, not just one of them. But, it contains only one distinct number, 5.
This is reminiscent of two Applicative Functor instances for lists, the [] and the ZipList. pure 5 :: [] Int indeed contains just one five, but pure 5 :: ZipList Int contains any amount of fives, but only fives. Of course it's hard to append infinite lists, so it's mainly just a curiosity here. A food for thought.
In any case it shows that there's more than just one way to write a code that typechecks here. There's more than just one list at our disposal here. The simplest one is indeed [], but the other one is .... our list itself!

Haskell Lists in List

I'm very new on Haskell, and I'm trying the following:
To obtain [1,2,3] from [[1,2,3],[4,5,6]]?
example :: [[a]] -> [a]
example [] = []
example [x:xs] = [x]
This example is returning [1] when input is [[1,2,3]] and if I add an other element in the main List, like [[1,2,3],[3,4,5]] then I have a Non-exhaustive pattern function.
You are quite close. In fact what you here want is some sort of "safe" head.
A list [a] has two constructors:
the empty list [], you cover this in the first case; and
the "cons" (x:xs).
It looks like you cover that in the second case, but in fact you do not: you put the pattern within square brackets. As a result, Haskell interprets your pattern as [(x:xs)]. So it thinks you match a singleton list (a list with one element), and that x is the head of the sublist, and xs the tail of the sublist.
In fact you want to cover (x:xs). If we use this pattern, there is another problem: x is the head of the list, so it has type [a]. Therefore we should return x, not [x], since in the latter case, we would wrap the sublist back in a list.
So a correct function is:
example :: [[a]] -> [a]
example [] = []
example (x:_) = x -- round brackets, x instead of [x]
Note that since we are not interested in the tail here, we use an underscore _. If you compile with all warnings (-Wall, or more specific -Wunused-matches) Haskell will otherwise complain about the fact that you declare a variable that you do not use.
Generalizing to a safeHead function
We can generalize this to some sort of generic safeHead :: b -> (a -> b) -> [a] -> b function:
safeHead :: b -> (a -> b) -> [a] -> b
safeHead d _ [] = d
safeHead _ f (x:_) = f x
Here we thus pass three arguments to safeHead: a value (of type b) we should return in case the list is empty; a function to post-process the head (type a -> b), and the list to process. In that case the example is equivalent to:
example :: [[a]] -> [a]
example = safeHead [] id
But we can also return a Maybe [a] here:
example2 :: [a] -> Maybe a
example2 = safeHead Nothing Just

Adding values to an ocaml list based on its existing values

I'm learning about the map and fold functions. I'm trying to write a function that takes a list and returns a list with all of the values in the original, each followed by that value's double.
Example: add_dbls [2;5;8] = [2;4;5;10;8;16]
Everything I try results in a list of lists, instead of a list. I'm struggling to come up with a better approach, using either map or fold (or both).
This is what I came up with originally. I understand why this returns a list of lists, but can't figure out how to fix it. Any ideas would be appreciated!
let add_dbls list =
match list with
| h::t -> map (fun a-> [a;(a*2)]) list
| [] -> []
Also, my map function:
let rec map f list =
match list with
| h::t -> (f h)::(map f t)
| [] -> []
You are nearly there. As you have observed, since we get list of lists, we need to flatten it to get a final list. List.concat function does exactly that:
let add_dbls list =
let l =
match list with
| h::t -> List.map (fun a -> [a;(a*2)]) list
| [] -> []
in
List.concat l
Here is the updated function that that computes the output that you require.
Now the output of add_dbls [2;5;8] = [2;4;5;10;8;16].
Although this works, it probably isn't efficient as it allocates a new list per item in your original list. Below are variations of the same function with different characteristics which depend on the size of l.
(* Safe version - no stack overflow exception. Less efficient(time and size) than add_dbls3 below. *)
let add_dbls2 l =
List.fold_left
(fun acc a -> (a*2)::a::acc)
[]
l
|> List.rev
(* Fastest but unsafe - stack overflow exception possible if 'l' is large - fold_right is not tail-recursive. *)
let add_dbls3 l =
List.fold_right
(fun a acc -> a::(a*2)::acc)
l
[]
It's should be simple to see that List.map always returns a list of the same length as the input list. But you want a list that's twice as long. So List.map cannot work for you.
You can solve this using List.fold_left or List.fold_right. If you're still having trouble after you switch to using a fold, you could update your question with the new information.
Update
The type of your fold function (a left fold) is this:
('a -> 'b -> 'a) -> 'a -> 'b list -> 'a
So, the folded function takes an accumulated answer and an element of the list, and it returns a new accumulated answer.
Your folded function is like this:
fun a b -> a::b::(b*2)
It attempts to use the :: operator to add new elements to the end of the accumulated list. But that's not what the :: operator does. It adds an element to the beginning of a list.
There's no particularly nice way to add an element to the end of a list. This is intentional, because it's a slow operation.
When using a left fold, you need to reconcile yourself to building up the result in reverse order and possibly reversing it at the end. Or you can use a right fold (which is generally not tail recursive).

Index of element in list in Haskell

How can I get the index of the element I am at in haskell when I am using map ?
For example I have this list l = "a+bc?|(de)*fg|h" and I want to know the exact index of the element I am at when I use the map or scanl function.
Amending Nikita Volkov's answer, you can use a function such as:
-- variant of map that passes each element's index as a second argument to f
mapInd :: (a -> Int -> b) -> [a] -> [b]
mapInd f l = zipWith f l [0..]
First of all, if you need an index when processing a list it is a certain sign that you're implementing a suboptimal algorithm, because list is not an index-based structure like array. If you need to deal with indexes you better consider using a vector instead.
Concerning your actual question, you can pair the items of your list with incrementing ints with the following code and then map over the result:
Prelude> zip [0..] "a+bc?|(de)*fg|h" :: [(Int, Char)]
[(0,'a'),(1,'+'),(2,'b'),(3,'c'),(4,'?'),(5,'|'),(6,'('),(7,'d'),(8,'e'),(9,')'),(10,'*'),(11,'f'),(12,'g'),(13,'|'),(14,'h')]