removing tuples from list (Haskell) - list

I want to write a function that takes as argument a list of tuples like this:
remove' [ ("a", True), ("b", False), ("c", False), ("d", True) ]
I would like to return a list of tuples that have False as their second value, so I'd like my function to return
[ ("b", False), ("c", False) ]
Here's what I have so far but it won't load in GHCi. can anyone help me out? Thanks
remove' :: [(a,b)] -> [(a,b)]
remove' [(a,b)] = [ c | c <- [(a,b)], c `notElem` True ]

Since you want to match the second element of the tuples, you need to pick the second element from the tuple and compare it with False like this
remove' :: [(a, Bool)] -> [(a, Bool)]
remove' xs = [c | c <- xs, snd c == False]
The snd function will get second element from each of the tuples and compare them with False. Only if they match, they will be gathered in the resulting list.
Since the second elements are booleans, you can make use of the not function like this
[c | c <- xs, (not . snd) c]
We can express the same wihtout the dot notation like this
[c | c <- xs, not(snd(c))]
Note: In your program, you have
remove' [(a,b)] = ...
it means that, it will be executed only when remove is called with a list of tuples of size 1. You can check that like this
remove' :: [(a, Bool)] -> [(a, Bool)]
remove' [(a, b)] = [(a, b)]
remove' [ ("a", True), ("b", False), ("c", False), ("d", True) ]
will print
Non-exhaustive patterns in function remove'
It means the patterns you specified in the function definition is not covering all the possible inputs. Since we need process a list of tuples of any length, we accept it in xs and use it in the List Comprehension.

I'm surprised no one has yet said
remove' = filter (not . snd)

You just need filter and select second item in lambda:
filter (\x -> (snd x) == False) [("a", False), ("b", True)]
Response:
[("a",False)]

Related

Generating a list of all truth assignments given a list of variables in SML?

I'm trying to write a function in SML that given a list of variables, it returns a list of tuples of every possible boolean assignment.
Essentially, I want the code to do this:
fun allAssignments ["p", "q"] =
[[("p", True), ("q", True) ]
[("p", True), ("q", False)]
[("p", False), ("q", True) ]
[("p", False), ("q", False)]]
However, I wrote this function and although it makes sense to me, I keep getting tycon mismatch errors and I can't rectify it:
fun allAssignments nil = [[]]
| allAssignments (x::xs) = [(x, true)::allAssignments xs] # [(x, false)::allAssignments xs]
Could anyone help point me in the right direction? Thanks!
Per your example, allAssignments needs to have the type string list -> (string * bool) list list (or potentially 'a list -> ('a * bool) list list or ''a list -> (''a * bool) list list, but I'll just stick with string for simplicity; the implementation is the same either way).
So, allAssignments xs must have the type (string * bool) list list, and (x, true) must have the type string * bool. But then (x, true) :: allAssignments xs is a type mismatch, because :: expects its second argument to be a list whose elements have the same type as its first argument, whereas in your case the second argument is a list whose elements are lists (which the first argument is not).
If we imagine a version of Standard ML that didn't actually check types, your version of allAssignments would give the following results:
allAssignments [] → [[]]
allAssignments ["q"] → [[("q", true), []], [("q", false), []]]
allAssignments ["p", "q"] → [[("p", true), [("q", true), []], [("q", false), []]], [("p", false), [("q", true), []], [("q", false), []]]]
As you can see, it doesn't really work out. One problem is that the assignments of "q" are nested in more levels of lists than the assignments of "p" (hence the type error). Another problem is that ("p", true) and ("p", false) each appear only once, whereas ("q", true) and ("q", false) each appear twice.
To fix this, you need to actually "open up" allAssignments xs and prepend (x, true) to each of the individual lists that it contains, and then the same for (x, false).
Here's one way, using map:
fun allAssignments nil = [nil]
| allAssignments (x::xs) =
(map (fn assignments => (x, true) :: assignments) (allAssignments xs))
# (map (fn assignments => (x, false) :: assignments) (allAssignments xs))
though I should mention that this implementation is not at all optimal; both the computation time and the memory usage can be reduced significantly, especially if you don't care about the order in which the assignments are returned.

How would you use map on a list of tuples that contains a list of tuples?

I have a list here that has the following structure:
list = [((1,1),[("A", 1), ("D", 4), ("E", 5)]), ((2,2),[("B", 2)]), ((3,3),[("C",3)])]
I want to output a list that has the following structure (aka summing the values of each of the second values of each sublist so for example (1+4+5) = 10
[((1,1),10), ((2,2),2), ((3,3),3))]
I am not sure how to get that structure by using map or even filter and the closest I have gotten is:
map snd (concat (map snd list))
which produces [1,4,5,2,3]
How would I achieve this structure?
First, write out the types:
have :: [((Int,Int), [(String,Int)])]
have = [ ((1,1),[("A", 1), ("D", 4), ("E", 5)]), ... ]
want :: [((Int,Int), Int)]
Evidently, the (Int,Int) isn't really relevant here, nor is the String. So our conversion function can be
give :: [(a, [(b, Int)])] -> [(a, Int)]
Furthermore, the a is just passed as-is, so the interesting bit is going to be [(b, Int)] -> Int. For this, you first need to throw away the bs
Prelude> map snd [("A", 1), ("D", 4), ("E", 5)]
[1,4,5]
and sum the result (composition!)
Prelude> sum . map snd $ [("A", 1), ("D", 4), ("E", 5)]
10
So sum . map snd is the function you'll need to apply to every RHS in the list of outer tuples.
How do you actually use it on only the RHS? Well, one way is to write a lambda
\(x,y) -> (x, f y)
...but actually there's a standard combinator for this, called second
second :: (b -> c) -> (d,b) -> (d,c)
(operating on the snd element of a tuple, applying a function† to it, putting it back in the tuple).
Prelude Control.Arrow> second (sum . map snd) (346, [("A", 1), ("D", 4), ("E", 5)])
(346,10)
All that's left to do is mapping that whole thing over the outer list:
Prelude Control.Arrow> map (second $ sum . map snd) [((1,1),[("A", 1), ("D", 4), ("E", 5)]), ((2,2),[("B", 2)]), ((3,3),[("C",3)])]
[((1,1),10),((2,2),2),((3,3),3)]
Or as a definition
give :: Num c => [(a, [(b, c)])] -> [(a, c)]
give = map . second $ sum . map snd
†If you look in the docs you'll find that second is actually more general than that: it can work not only with functions, but general arrows ~>, i.e. second :: Arrow (~>) => (b ~> c) -> ((d,b)~>(d,c)). If that's confusing to you, don't worry... in most applications, the arrow will just be the normal function one.
If you don't mind the map you could use list comprehension here:
list = [((1,1),[("A",1),("D",4),("E",5)]),((2,2),[("B",2)]),((3,3),[("C",3)])]
[(fst x, sum [snd y | y <- (snd x) ]) | x <- list]
returns
[((1,1),10),((2,2),2),((3,3),3)]

Tuples Pattern Matching list Haskell

I am trying to implement a function where I have a list of 2-tuples and it returns the tuples that correspond to True. The first character is a String and the second character is a Boolean. This is what I want:
pack [ ("a", True), ("b", False), ("c", False), ("d", True) ]
returns [ ("a", True), ("d", True) ]
Here is my code:
pack :: [String] -> [Bool] -> [(String, Bool)]
pack [] [] = []
pack (x:xs) [] = []
pack [] (y:ys) = []
pack (x:xs) (True:ys) = (x, True) : pack xs ys
pack (x:xs) (False:ys) = pack xs ys
I can only get { returns [("a", True), ("d", True)] } only by typing in
pack ["a", "b", "c", "d"] [True, False, False, True]
and this is not what I want and am confused how to approach this. Any help, guidance, or link would be much appreciated.
I'm going to use the description of what you are trying to implement to show you what my steps towards a solution would be. Hopefully that helps you converge on your own solutions in the future.
If I rephrase it, you want a function with the following signature:
pack :: [(String, Bool)] -> [(String, Bool)]
That is, you have a list of 2-tuples (the first element being a String, the second element being a Bool) and you want to end up with a list of the same type.
You want to filter all the tuples of this list and only keep the ones with a True value. The prelude happens to have a function just for that:
filter :: (a -> Bool) -> [a] -> [a]
The first argument of filter, a function a -> Bool called a predicate, lets you define what you want to keep in the second argument (the first [a]).
Note that a can be any type at all, so we could replace a with (String, Bool) and filter would have the following type:
filter :: ((String, Bool) -> Bool) -> [(String, Bool)] -> [(String, Bool)]
It's starting to look closer and closer to our target signature for pack! What we are missing is the predicate (String, Bool) -> Bool that will tell filter what we want to keep:
isTrue :: (String, Bool) -> Bool
isTrue (_, True) = True
isTrue (_, False) = False
Finally, we can implement pack in term of filter and isTrue:
pack :: [(String, Bool)] -> [(String, Bool)]
pack = filter onlyTrue
You've mentioned in a comment that you do not want to use any "built-in" function. Let's get rid of filter then, and write pack closer to the original style you've posted:
pack [] = []
pack (x:xs)
| isTrue x = x : pack xs
| otherwise = pack xs

Throwing away element in index,element tuples

New to Haskell, and trying to construct an [[(Int, Int)]] where each element is its corresponding grid position, constructed from another board [[a]]. Therefore a square [[a]] of side length 3 would create
[[(0, 0), (1, 0), (2, 0)]
,[(0, 1), (1, 1), (2, 1)]
,[(0, 2), (1, 2), (2, 2)]]
(eventually I'll be iterating over this with a map (map ...) into a function of type [[a]] -> (Int, Int) -> b to create a [[b]], so if I'm missing something massively easier, let me know!)
In Python I might do something like:
[[(x,y) for (x,_) in enumerate(board[y])] for (y,_) in enumerate(board)]
That is to say, I'd use the enumerate builtin to construct (index, element) tuples and throw away the element.
I know in Haskell I can do:
[[(x,y) | x <- [0..length (board!!y)-1]] | y <- [0..length board-1]]
but those sorts of constructions in Python (for foo in range(len(bar))) are a bit of an anti-pattern and heavily discouraged. Is that true in Haskell, as well?
If I were to write the Haskell like I'd write the Python, I'd do:
[[(x,y) | (x,_) <- zip [0..] (board!!y)] | (y,_) <- zip [0..] board]
Is that frowned upon?
Your final "write it like Python" suggestion is almost good, but you are unnecessarily throwing away the rows of the board, and then re-creating them with (!!). Writing it like this instead would be perfectly fine:
board :: [[Char]]
board = ["abc", "def", "ghi"]
board' :: [[(Int, Int)]]
board' = [[(x, y) | (x, _) <- zip [0..] row]
| (y, row) <- zip [0..] board]
Well usually the (!!) :: [a] -> Int -> a is not really a nice operator: it requires O(k) time to access the k-th element. For your small example that is of course not really an issue, but it can turn some algorithms from O(n) into O(n2).
Usually in Haskell, one aims to avoid it by writing clever algorithms that can iterate through the list, instead of obtaining a (random) index.
In Python you can rewrite your:
[[(x,y) for (x,_) in enumerate(board[y])] for (y,_) in enumerate(board)]
into:
[[(x,y) for (x,_) in enumerate(by)] for (y,by) in enumerate(board)]
and the equivalent in Haskell would be:
[ [ (x,y) | (x,_) <- zip [0..] by ] | (y,by) <- zip [0..] board ]
Or we can make the code cleaner by first introducing an enumerate :: (Enum a, Num a) => [b] -> [(a, b)] function in Haskell:
enumerate :: (Enum a, Num a) => [b] -> [(a, b)]
enumerate = zip [0..]
and then write:
[ [ (x,y) | (x,_) <- enumerate by ] | (y,by) <- enumerate board ]
Your aside seems to suggest you might be interested in the following function, sometimes called mapWithIndex (e.g., in containers) and sometimes called imap (in lens).
mapWithIndex :: (Int -> a -> b) -> [a] -> [b]
mapWithIndex f = go 0
where
go !_i [] = []
go i (x : xs) = f i x : go (i + 1) xs
So mapWithIndex (\i -> mapWithIndex (\j y -> (i,j,y))) will take a list of lists and annotate each element with its position. Of course, rather than annotating, you can perform an arbitrary calculation.

Haskell: cross product of a list with subsequences of another list

I have another question regarding generating lists of stuff from various sources.
UPDATED: Simplified the example
I have a list of variables
["a", "b", "c"]
and bool values
[False, True].
Now I want to have a list with all subsequences of the variables list crossed with the values list so for each entry the list of subsequences of the variables has, a set of pairs with each of the possible values.
For the lists above I'd get this (complete list for this scenario). As the empty list won't pair with the other list too well, I don't care whether it is part of the result list or not (can be added later easily).
[
[],
[("a", False)],
[("a", True)],
[("b", False)],
[("b", True)],
[("c", False)],
[("c", True)],
[("a", False), ("b", False)],
[("a", False), ("b", True)],
[("a", True), ("b", False)],
[("a", True), ("b", True)],
[("a", False), ("c", False)],
[("a", False), ("c", True)],
[("a", True), ("c", False)],
[("a", True), ("c", True)],
[("b", False), ("c", False)],
[("b", False), ("c", True)],
[("b", True), ("c", False)],
[("b", True), ("c", True)],
[("a", False), ("b", False), ("c", False)],
[("a", False), ("b", False), ("c", True)],
[("a", False), ("b", True), ("c", False)],
[("a", False), ("b", True), ("c", True)],
[("a", True), ("b", False), ("c", False)],
[("a", True), ("b", False), ("c", True)],
[("a", True), ("b", True), ("c", False)],
[("a", True), ("b", True), ("c", True)],
]
If it was permutations only, a call to permutations combined with a comprehension would suffice, but I have no idea how to get the list for the subseqences easily.
I could do with using the "call to permutations + comprehension"-approach on the lists with different sizes but that doesn't sound very elegant.
Is there a straightfoward solution to that?
import Control.Monad (forM)
import Data.List (subsequences)
solution :: [a] -> [b] -> [[(a, b)]]
solution variables values = do
sequence <- subsequences variables
forM sequence $ \variable -> do
value <- values
return (variable, value)
Proof that it works:
>>> mapM_ print $ solution ["a", "b", "c"] [False, True]
[]
[("a",False)]
[("a",True)]
[("b",False)]
[("b",True)]
[("a",False),("b",False)]
[("a",False),("b",True)]
[("a",True),("b",False)]
[("a",True),("b",True)]
[("c",False)]
[("c",True)]
[("a",False),("c",False)]
[("a",False),("c",True)]
[("a",True),("c",False)]
[("a",True),("c",True)]
[("b",False),("c",False)]
[("b",False),("c",True)]
[("b",True),("c",False)]
[("b",True),("c",True)]
[("a",False),("b",False),("c",False)]
[("a",False),("b",False),("c",True)]
[("a",False),("b",True),("c",False)]
[("a",False),("b",True),("c",True)]
[("a",True),("b",False),("c",False)]
[("a",True),("b",False),("c",True)]
[("a",True),("b",True),("c",False)]
[("a",True),("b",True),("c",True)]
solution :: [a] -> [b] -> [[(a, b)]]
solution variables values = do
as <- subsequences variables
bs <- forM as $ const values
zip as bs
And to demonstrate that it works:
Data.List Control.Monad Prelude> :{
Data.List Control.Monad Prelude| let solution :: [a] -> [b] -> [[(a, b)]]
Data.List Control.Monad Prelude| solution variables values = do
Data.List Control.Monad Prelude| as <- subsequences variables
Data.List Control.Monad Prelude| bs <- forM as $ const values
Data.List Control.Monad Prelude| return $ zip as bs
Data.List Control.Monad Prelude| :}
Data.List Control.Monad Prelude> solution [ "a", "b", "c" ] [ False, True ]
[[],[("a",False)],[("a",True)],[("b",False)],[("b",True)],[("a",False),("b",False)],[("a",False),("b",True)],[("a",True),("b",False)],[("a",True),("b",True)],[("c",False)],[("c",True)],[("a",False),("c",False)],[("a",False),("c",True)],[("a",True),("c",False)],[("a",True),("c",True)],[("b",False),("c",False)],[("b",False),("c",True)],[("b",True),("c",False)],[("b",True),("c",True)],[("a",False),("b",False),("c",False)],[("a",False),("b",False),("c",True)],[("a",False),("b",True),("c",False)],[("a",False),("b",True),("c",True)],[("a",True),("b",False),("c",False)],[("a",True),("b",False),("c",True)],[("a",True),("b",True),("c",False)],[("a",True),("b",True),("c",True)]]
Data.List Control.Monad Prelude> forM_ it print
[]
[("a",False)]
[("a",True)]
[("b",False)]
[("b",True)]
[("a",False),("b",False)]
[("a",False),("b",True)]
[("a",True),("b",False)]
[("a",True),("b",True)]
[("c",False)]
[("c",True)]
[("a",False),("c",False)]
[("a",False),("c",True)]
[("a",True),("c",False)]
[("a",True),("c",True)]
[("b",False),("c",False)]
[("b",False),("c",True)]
[("b",True),("c",False)]
[("b",True),("c",True)]
[("a",False),("b",False),("c",False)]
[("a",False),("b",False),("c",True)]
[("a",False),("b",True),("c",False)]
[("a",False),("b",True),("c",True)]
[("a",True),("b",False),("c",False)]
[("a",True),("b",False),("c",True)]
[("a",True),("b",True),("c",False)]
[("a",True),("b",True),("c",True)]
An easy solution to generate all subsequences of a given list (without thinking about performance) is:
subs :: [a] -> [[a]]
subs [] = [[]]
subs (x:xs) = subs xs ++ map (x:) (subs xs)
Actually there is no need to use monads here. The following might be a bit intimidating at first, but I will explain afterwards. Note: Mapping and folding helps the compiler make code faster.
solution :: [a] -> [b] -> [[(a, b)]]
solution variables values = foldr (<*>) [[]]
$ map (\variable -> id : map (\value -> (:) (variable, value) ) values)
$ variables
It needs Control.Applicative.
The idea is to have picking the subsequence and assigning all possible values as a single process. The function (\value -> (:) (variable, value) ) :: b -> [(a,b)]->[(a,b)] takes one value, makes a pair with a variable and produces a function appending this pair to a list of variable-value-pairs.
By mapping this over the list of all values, we get a list of functions map (\value -> (:) (variable, value) ) values :: [[(a,b)]->[(a,b)]]. The outer list brackets are for nondeterminism and the inner for the list of bindings.
We add a further option: Not assigning a value. This is done by id :: [(a,b)]->[(a,b)], which is added to the list of possibilities.
The next lambda-abstraction-and-map construction takes the different variables into account: We want to have a list of possible changes for every variable.
map (\variable -> (id : map (\value -> (:) (variable, value) ) values)) variables
has type [[[(a,b)]->[(a,b)]]] where the outer-most list is for variables that are to be bound, the middle layer for nondeterminism and the inner list for variables already bound.
Then comes the big finally: Folding! The fold works on the outer-most list layer (for every variable do something) and this level of list-ness disappears. The (<*>) combines all the nondeterminism, which was the middle layer of lists before and is the outer layer of the result. The inner layer is unaffected. The starting value of the fold is [[]]::[[(a,b)]].
If you get used to the Alternative interface for nondeterminism you might prefer
solution :: Alternative f => [a] -> f b -> f[(a, b)]
solution variables values = foldr (<*>) (pure [])
$ map (\variable -> pure id <|> pure (\value -> (:) (variable, value)) <*> values)
$ variables
because now the list operations (:) and map are for the list of variables while everything concerning nondeterminism is handled by the applicative/ alternative interface.