Given two lists, [a, b] and [c, d], I'd like to get the following result:
[(a,c), (a,d), (b,c), (b,d)]
How can I do this in Haskell? Is there a built-in function for this, or should I implement one myself?
[ (x,y) | x<-[a,b], y<-[c,d] ]
This doesn't really require any further explanation, does it?
Applicative style all the way!
λ> :m + Control.Applicative
λ> (,) <$> ['a','b'] <*> ['c','d']
[('a','c'),('a','d'),('b','c'),('b','d')]
(I've eschewed any String syntactic sugar above, in order to stay close to your example.)
For information, (,) is special syntax for a function that takes two arguments and makes a pair out of them:
λ> :t (,)
(,) :: a -> b -> (a, b)
Edit: As noted by leftaroundabout in his comment, you can also use liftA2:
λ> :m + Control.Applicative
λ> let combine = liftA2 (,)
λ> combine "ab" "cd"
[('a','c'),('a','d'),('b','c'),('b','d')]
How can you do this in an imperative pseudocode?
for each element x in [a,b]:
for each element y in [c,d]:
produce (x,y)
In Haskell, this is written as
outerProduct xs ys =
do
x <- xs -- for each x drawn from xs:
y <- ys -- for each y drawn from ys:
return (x,y) -- produce the (x,y) pair
(following comments by leftaroundabout) this is of course extremely close to how liftM2 monadic combinator is defined, so in fact
outerProduct = liftM2 (,)
which is the same as liftA2 (,), and its various re-writes in terms of list comprehensions, concatMap function, >>=, <$> and <*> operators.
Conceptually though this is the stuff of the Applicative – which would be better named as Pairing, – because this pairing up of the elements of two "containers" ⁄ "carriers" ⁄ whatever is exactly what Applicative Functor is about. It just so happens that Haskell's do notation works for monads, and not (yet) for applicatives.
In some sense compile-time nested loops are Applicative ⁄ Pairing functors; Monads add the ability to create nested loops on the fly, depending on the values produced by an "outer" enumeration.
The most inuitive would be using list comprehension, other aproaches include using applicative functors:
(,) <$> [1,2,3] <*> [4,5,6]
So what does this do?
Remember that (,) :: a -> b -> (a, b) Takes two arguments and returns a tuple.
<$> is acutally fmap, (<$>) :: Functor f => (a -> b) -> f a -> f b
It takes a function and lift it. In this case it takes (,) and lift it to work on list. So let x = (,) <$> [1,2] would generate x :: [b -> (Integer, b)] which is the the list of functions that takes b and returns tuple with one fixed argument (Integer,b). Finally we apply it using <*> to generate all the combinations.
use List Comprehension:
s = [a,b]
s' = [c,d]
all_combinations = [(x,y) | x <- s, y <- s']
Related
so I am new to OCaml and im having some trouble with lists.
What I have is a List of chars as follows:
let letters = [a;b;c;d]
I would like to know how can I iterate the list and apply a fuction that takes as arguments every possible combination of two chars on the list (do_someting char1 char2), for example: a and b (do_something a b), a and c .... d and b, d and c; never repeating the same element (a and a or c and c should not happen).
OCaml is a functional language, so we want to try to break down the procedure into as many functional pieces as we can.
Step 1 is "take a list of things and produce all combinations". We don't care what happens afterward; we just want to know all such combinations. If you want each combination to appear only once (i.e. (a, b) will appear but (b, a) will not, in your example), then a simple recursive definition will suffice.
let rec ordered_pairs xs =
match xs with
| [] -> []
| (x :: xs) -> List.append (List.map (fun y -> (x, y)) xs) (ordered_pairs xs)
If you want the reversed duplicates ((a, b) and (b, a)), then we can add them in at the end.
let swap (x, y) = (y, x)
let all_ordered_pairs xs =
let p = ordered_pairs xs in
List.append p (List.map swap p)
Now we have a list of all of the tuples. What happens next depends on what kind of result you want. In all likelihood, you're looking at something from the built-in List module. If you want to apply the function to each pair for the side effects, List.iter does the trick. If you want to accumulate the results into a new list, List.map will do it. If you want to apply some operation to combine the results (say, each function returns a number and you want the sum of the numbers), then List.map followed by List.fold_left (or the composite List.fold_left_map) will do.
Of course, if you're just starting out, it can be instructive to write these List functions yourself. Every one of them is a simple one- or two- line recursive definition and is very instructive to write on your own.
I'm just starting to learn Haskell, and I have to create a function composite that receives two lists a, b :: [(String, String)] as inputs, and outputs a new list c :: [(String, String)], which is a 'composition' of both a and b. Specifically, list c has to include only those pairs (p,q), where there is a r such that:
(p,r) is in a
(r,q) in in b
For example:
composite [("1","2")] [("2","3"), ("2","4")] == [("1","3"), ("1","4")]
composite [("1","2"), ("5","2")] [("2","3"), ("2","4")] == [("1","3"), ("1","4"), ("5","3"), ("5","4")]
composite [("1","2"), ("1","4"), ("1","5")] [("2","3"), ("4","3")] == [("1","3")]
How can I do this?
You can combine the lists using a list comprehension over multiple lists:
[(x,z)|(x,y) <- a, (y',z) <- b, y == y' ]
Note that the result is the list if (x,z) tuples, and the inputs are the lists of (x,y) and (y,z) tuples.
I have tried this in http://tryhaskell.org with your list test case; feel free to copy-paste it there and play around with it:
[(x,z) | (x,y) <-[('a', 'b'), ('a', 'd'), ('a', 'e')],(y',z) <- [('b','c'), ('d','c')], y == y']
This yields:
[('a','c'),('a','c')]
There are a few other things to note.
First, the y == y'. As #chi points out, if you use 'y' again in the list comprehension, the system does not consider it the same variable. You need to use a new variable, y' (or any other name) and explicitly tell Haskell that y and y' should have the same value.
Second, we're not using capitals; Haskell is case-sensitive and uses capitals for other purposes.
Third, you don't have to make it only for Strings. The function can operate on tuples of arbitrary types:
composite :: [(a,a)] -> [(a,a)] -> [(a,a)]
As #Daniel Wagner observes in the comments, it's actually a little more complicated:
composite :: (Eq a) => [(a,a)] -> [(a,a)] -> [(a,a)]
The Eq a tells Haskell that a is something that you can compare for equality. Formally, a is a member of the Eq type class.
He also observes that we can generalize this further: the lefthand side of the tuples in list A don't have to be of the same type as the righthand side of the tuples in list B. So you could have, for example, a list of (Int,String) and a list of (String,Char), and match them on the String. The type would become:
composite :: Eq b => [(a, b)] -> [(b, c)] -> [(a, c)]
A final thing to note is that there may be duplicates in your resulting list. This is the case in your third test case.
The exercise probably doesn't require you to remove the duplicates.. yet.
Haskells libraries provide tools to remove duplicates. In a production setting, you should use these tools. But when learning, writing your own code to remove duplicates may be a useful exercise.
I've also got it in ideone.org. Don't worry about the "main" and "print" over there for now; just experiment with the function and see if you understand it.
S.L. Barth is on the right track, but isn't quite there. What you need to do is to go through the cartesian product of both lists, compare the y parts and if they match, then you can emit a tuple on the output.
This can easily be done with a list comprehension, such as this one:
[(x, z) | (x, y1) <- a, (y2, z) <- b, y1 == y2]
You should be able to wrap this in a function.
Note that if you want the function to be polymorphic, the type of it needs an Eq y constraint so that you can actually compare the y parts:
composite :: Eq y => [(x, y)] -> [(y, z)] -> [(x, z)]
I have a list of tuples, for example:
[(1,2), (3,4), (5,6)]
Now I have to write function which sum up the first an second element of each tuple and create a list of these values.
For the example above it should be:
[3, 7, 11]
This should be done with use of list comprehension. It's not allowed to use functions like map, filter and contact.
Any ideas how I could access the elements of the tuple in the list?
Try this:
[ x + y | (x,y) <- yourlist]
The trick is representing the two elements in a tuple from your input list as x and y and then dealing with them as needed.
Let's do it without list comprehensions, using functions from the Prelude:
map (uncurry (+)) [(1,2), (3,4), (5,6)]
-- Result: [3, 7, 11]
How does this work? Let's consider the types:
(+) :: Num a => a -> a -> a
uncurry :: (a -> b -> c) -> (a, b) -> c
map :: (a -> b) -> [a] -> [b]
As you may already know, in Haskell, the normal way of doing multi-argument functions is by **currying* them. The type of (+) reflects this: conceptually it takes one argument and produces a function that then takes the "second" argument to produce the final result.
uncurry takes such a curried two-argument function and adapts it to work on a pair. It's trivial to implement:
uncurry :: (a -> b -> c) -> (a, b) -> c
uncurry f (a, b) = f a b
Funnily enough, the uncurry function is curried, so its partial application uncurry (+) has type Num a => (a, a) -> a. This would then be a function that takes a pair of numbers and adds them.
And map simply applies a function to every element of a list, collecting the individual results into a list. Plug them all together and that's a solution.
This will be a TicTacToe implementation:
data Row = A | B | C deriving (Show, Read, Eq, Ord, Enum, Bounded)
data Column = X | Y | Z deriving (Show, Read, Eq, Ord, Enum, Bounded)
type Pos = (Row, Column)
data Player = Player String
data Field = Field [(Pos, Player)]
initialField :: Field
initialField = Field []
As you can see, the initialField is just an empty list and as players make moves, (pos, player) tupels will get added to the list. So far so good. But now I have trouble writing a possibleMoves :: Field -> [Pos] function to get the empty fields. How do I iterate over all Row, Column possibilities in Haskell? I get the feeling that my approach is wrong, but I'm new to Haskell so I have no better idea.
We can get all positions with list comprehensions (see also the other answers)
positions :: [Pos]
positions = [(r,c) | r <- [A,B,C], c <- [X,Y,Z]]
and all plays with a map
occupied :: Field -> [Pos]
occupied (Field l) = fmap fst l
Then we can define possibleMoves (you will need to import Data.List to get \\, list difference):
possibleMoves :: Field -> [Pos]
possibleMoves f = positions \\ (occupied f)
A somewhat more compact version takes advantage of list comprehension constraints:
possibleMoves :: Field -> [Pos]
possibleMoves (Field l) = [(r,c) | r <- [A,B,C], c <- [X,Y,Z], (r,c) `notElem` occupied]
where occupied = fmap fst l
All rows (ref = Getting a list of all possible data type values in Haskell):
Prelude> [(minBound :: Row) ..]
[A,B,C]
All columns:
Prelude> [(minBound :: Column) ..]
[X,Y,Z]
The compute the Cartesian product to find all possibilities (ref = Cartesian product of 2 lists in Haskell):
Prelude> [(x, y) | x <- [(minBound :: Row)..], y <- [(minBound :: Column)..]]
[(A,X),(A,Y),(A,Z),(B,X),(B,Y),(B,Z),(C,X),(C,Y),(C,Z)]
If you want an ultra short, "ulta-Haskelly" version:
enumAll :: (Bounded a, Enum a) => [a]
enumAll = [minBound..maxBound]
positions :: [Pos]
positions = (,) <$> enumAll <*> enumAll
(You'll also need to import Control.Applicative for the <$> and <*> operators)
Then in ghci:
*Main> positions
[(A,X),(A,Y),(A,Z),(B,X),(B,Y),(B,Z),(C,X),(C,Y),(C,Z)]
How the hell does this work?
enumAll is just a generic helper function (I was surprised not to be able to quickly find it in the standard libraries; it's possible I missed it and you don't even need to define it yourself). It gives you a list of every possibility for any bounded enumerable type. It's fairly straightforward; Bounded means the type has minBound and maxBound, Enum means you can use the [a..b] syntax to get a list of everything from a to b.
(,) is just the pair-building function. If you type :t (,) into ghci, it tells you (,) :: a -> b -> (a, b).
Now, what about those weird <$> and <*> symbols? They're basically "special" forms of function application. So you can read it almost like we're simply applying (,) to the two arguments enumAll and enumAll. But because it's "special" application, it doesn't just give us the pair (enumAll, enumAll).
What we're doing here is using the Applicative instance for lists. I'm not going to get into that in full detail, but what this does is help us think that [Row] is not a list of row values, but rather a single "unknown" row value. It's a value that could be any element of the list, but we don't know which one. The technical term usually used for this is that [Row] can be thought of as a nondeterministic Row; it's a Row value that could be a number of possibilities, but we haven't been able to determine which one it actually is.
So what we're doing is applying the function (,) (which just takes two arguments to build a pair), to two nondeterminsitic values, to get a nondeterminsitic pair (this is where we need the "special" version of function application with <$> and <*>; if we apply (,) normally with (,) enumAll enumAll or build the pair directly with (enumAll, enumAll) then all we get is a normal pair of nondeterminsitic values, instead of a nondeterministic pair of normal values - ([a], [b]) vs [(a, b)]) . And if I take a pair from all possibilities of one bounded enum and all possibilities of another bounded enum, then I should get all possibilities of pair! Which is exactly what happens.
The type signature positions :: [Pos] is actually necessary here. That's what tells Haskell we're building a list of (Row, Column) pairs rather than any other kind of pair of enums, which is how it knows that the first enumAll was enumerating all rows and the second wsa enumerating all columns. The most general type (,) <$> enumAll <*> enumAll is actually (Enum a, Bounded a, Enum b, Bounded b) => [(a, b)], which will work just fine but is a pain to work with interactively in ghci because you'll keep getting ambiguous type variables whenever you try to print things.
I've only been at Haskell for two days now, and was wondering what the difference between the two function definitions below are:
Prelude> let swap (x1:x2:xs) = x2:x1:xs
Prelude> swap [1..5]
[2,1,3,4,5]
Prelude> let swap' (x1:x2:xs) = [x2] ++ [x1] ++ xs
Prelude> swap' [1..5]
[2,1,3,4,5]
That is, what makes x2:x1:xs different from [x2] ++ [x1] ++ xs ?
Please and thanks.
The type signatures are a good place to start:
(:) :: a -> [a] -> [a]
(++) :: [a] -> [a] -> [a]
You can find these out with :type (:) and :type (++) in ghci.
As you can see from the type signatures, both are used to produce lists.
The : operator is used to construct lists (and to take them apart again for pattern matching). To make a list [1,2,3] you just build it up with 1 : 2 : 3 : []. The first element of : is the item to add on the front of the list, and the second element is either a list (also built up with : or the empty list signified by []).
The ++ operator is list concatenation. It takes two lists and appends them together. [1,2,3] ++ [4,5,6] is legal, whereas 1 ++ [1,2,3] is not.
This has nothing to do with syntax. (:) and (++) are just different operators. (:) is a constructor who constructs a list from an element and another list. (++) makes a new list that is the concatenation of two lists. Because (++) is not a constructor you can't use it in patterns.
Now we come to Syntax: the notation
[x2]
that you use is a shorthand for
x2:[]
So what you really have done in the second example is:
(x2:[]) ++ (x1:[]) ++ xs
Therefore, when constructing a list, you can't avoid (:), it's ultimatively the only way to do it. Note that you must construct intermediate lists to be able to use (++).