I am attempting to understand how to use zip in Haskell. I've been learning Haskell recently and am trying to create a list of tuples from two separate lists
I have the following:
createList :: [Char] -> [Char] -> [(Char,Char)]
createList xs ys = zip(xs,ys)
I understand zip is supposed to create a list of tuples given two lists, but I get the following error:
Couldn't match expected type ‘[a0]’
with actual type ‘([Char], [Char])’
Can anyone explain to me where I am stumbling?
Haskell function calls don't use brackets or commas.
You can write the createList function as:
createList xs ys = zip xs ys
or simply
createList = zip
Thus, the createList function is redundant; it's just zip. The only potential use for the alias that I can think of is if you truly want to constrain the type as given.
If you remove the parenthesis around zip call, your code should work:
createList :: [Char] -> [Char] -> [(Char,Char)]
createList xs ys = zip xs ys
Explanation:
Full error I am getting when I run zip ([1, 2, 3], [4, 5, 6]) (notice the parens):
<interactive>:4:5:
Couldn't match expected type ‘[a]’
with actual type ‘([Integer], [Integer])’
Relevant bindings include
it :: [b] -> [(a, b)] (bound at <interactive>:4:1)
In the first argument of ‘zip’, namely ‘([1, 2, 3], [4, 5, 6])’
In the expression: zip ([1, 2, 3], [4, 5, 6])
In an equation for ‘it’: it = zip ([1, 2, 3], [4, 5, 6])
Notice the part that says In the first argument of ‘zip’, namely ‘([1, 2, 3], [4, 5, 6])’. The parens are interpreted as tuple constructor. zip function expects a list as its first argument but we are passing it a tuple.
Related
Given a list of lists, I'd like to find the maximum number of times a particular element occurs in one of the sub-lists.
So given [[1,4],[4,3],[1,4,4,3]] I expect output to be 2 because the number 4 occurs twice in one of the sub-lists (and no more than twice).
My approach was to eliminate all the numbers which are not 4 from the sublists, and then get the maximum length of all the sub-lists. The first step was OK:
map (filter (==4)) [[1,4],[4,3],[1,4,4,3]]
But adding length gives me an error:
map (length $ filter (==4)) [[1,4],[4,3],[1,4,4,3]]
Couldn't match expected type ‘[Integer] -> b’
with actual type ‘Int’
Relevant bindings include it :: [b] (bound at <interactive>:11:1)
In the first argument of ‘map’, namely ‘(length $ filter (== 4))’
In the expression:
map (length $ filter (== 4)) [[1, 4], [4, 3], [1, 4, 4, ....]]
In an equation for ‘it’:
it = map (length $ filter (== 4)) [[1, 4], [4, 3], [1, 4, ....]]
Why doesn't this work? - Haskell noob if you did't notice :)
You just need to compose length and filter (==4) with ., not $, because both length and filter (==4) are functions, not a function and a value, which you use $ for.
So you have:
map (length . filter (==4)) [[1,4],[4,3],[1,4,4,3]]
Alternatively, this would work also:
map (\x -> length $ filter (==4) x) [[1,4],[4,3],[1,4,4,3]]
but notice in this case you're applying filter (==4) x to length and filter (==4) x is a value itself, not a function, so $ is the correct composition operator.
But I'd argue the former is better Haskell style.
I have a list, for example [1, 2, 3, 4, 5] and I have to duplicate each element of the list to form a list like [1, 1, 2, 2, 3, 4, 4, 5, 5].
As a hint, we're referred to the concat function which flattens a list of lists into a single list. But to try and understand how you would go about this in Haskell better, I'm trying to do it manually. Here is my attempt:
duplicate :: [a] -> [a]
duplicate [] = []
duplicate (x:xs) = x : (x:xs) duplicate xs
With the error message:
Couldn't match expected type `((a0 -> Bool) -> [a0] -> [a0])
-> [a] -> [a]'
with actual type `[a]'
The function `x : xs' is applied to two arguments,
but its type `[a]' has none
In the second argument of `(:)', namely `(x : xs) myTakeWhile xs'
In the expression: x : (x : xs) myTakeWhile xs
Failed, modules loaded: none.
My way of thinking is that you cons the head of the list to the whole list and then recursively call the function on the tail of this list. For example in pseudocode:
duplicate [1, 2, 3]
1 : [1, 2, 3] duplicate [2, 3]
2 : [2, 3] duplicate [3]
3: [3] duplicate []
return list [1, 1, 2, 2, 3, 3]
Is this an idiomatic way of approaching this problem and where am I going wrong in my attempt syntactically? I'm not looking for alternative, more efficient code solutions to this, I'm merely trying to get used to the functional way of approaching problems as opposed to imperative ways of looking at things.
Thanks!
The definition you're looking for is:
duplicate :: [a] -> [a]
duplicate [] = []
duplicate (x:xs) = x : x : duplicate xs
Since : is a right-associative operator, you can read that last alternative as
duplicate (x:xs) = x : (x : (duplicate xs))
or as
duplicate (x:xs) = (:) x ((:) x (duplicate xs))
Keeping in mind that [1, 2, 3] is just short for 1 : 2 : 3 : [], when duplicate is applied to [1, 2, 3], the second alternative is used because it matches the pattern x : xs (namely with x = 1 and xs = 2 : 3 : []). You want the result to begin twice with the head (which is the x : x : ... part of the definition), and continue with the duplicated tail (the ... : duplicate xs part).
I am starting to learn haskell, but cannot find a way to have a working main function. I have already made it work somehow, but I think it was pure luck because I cannot get it again.
Basically, what I want to do is create a script file to be run like runhaskell script.hs from terminal.
So the basic structure would be the function declaration followed by a main = do or something, and the function being called to print its result.
For example, I took this from "Learn you a Haskell", but the following code doesn't work:
elem' :: (Eq a) => a -> [a] -> Bool
elem' y ys = foldl (\acc x -> if x == y then True else acc) False ys
main :: IO()
main = print (elem' 1 [1,2,3,4])
This gives me the error:
Build FAILED
/home/helton/Desktop/apaga.hs: line 6, column 16:
Warning: Defaulting the following constraint(s) to type `Integer'
(Eq a0)
arising from a use of elem'
at /home/helton/Desktop/apaga.hs:6:16-20
(Num a0)
arising from the literal `1' at /home/helton/Desktop/apaga.hs:6:22
In the first argument of `print', namely `(elem' 1 [1, 2, 3, 4])'
In a stmt of a 'do' block: print (elem' 1 [1, 2, 3, 4])
In the expression: do { print (elem' 1 [1, 2, 3, 4]) }
print (elem' 1 [1,2,3,4])
While I expected something like
> True
Try replacing
print (elem' 1 [1, 2, 3, 4])
with
print (elem' (1::Int) [1, 2, 3, 4])
The issue here is that Haskell can't determine whether your numeric literals should be interpreted as Ints or Doubles or any other numeric type.
Specifying the type for any numeric literal here is enough, since elem' requires all of them to be of the same type, hence once the type of any one of them is known such type can be used for everything else.
I have a given list, e.g. [2, 3, 5, 587] and I want to have a complete list of the combination. So want something like [2, 2*3,2*5, 2*587, 3, 3*5, 3*587, 5, 5*587, 587]. Since I am on beginner level with Haskell I am curious how a list manipulation would look like.
Additionally I am curious if the computation of the base list might be expensive how would this influence the costs of the function? (If I would assume the list has limit values, i.e < 20)
Rem.: The order of the list could be done afterwards, but I have really no clue if this is cheaper within the function or afterwards.
The others have explained how to make pairs, so I concern myself here with getting the combinations.
If you want the combinations of all lengths, that's just the power set of your list, and can be computed the following way:
powerset :: [a] -> [[a]]
powerset (x:xs) = let xs' = powerset xs in xs' ++ map (x:) xs'
powerset [] = [[]]
-- powerset [1, 2] === [[],[2],[1],[1,2]]
-- you can take the products:
-- map product $ powerset [1, 2] == [1, 2, 1, 2]
There's an alternative powerset implementation in Haskell that's considered sort of a classic:
import Control.Monad
powerset = filterM (const [True, False])
You could look at the source of filterM to see how it works essentially the same way as the other powerset above.
On the other hand, if you'd like to have all the combinations of a certain size, you could do the following:
combsOf :: Int -> [a] -> [[a]]
combsOf n _ | n < 1 = [[]]
combsOf n (x:xs) = combsOf n xs ++ map (x:) (combsOf (n - 1) xs)
combsOf _ _ = []
-- combsOf 2 [1, 2, 3] === [[2,3],[1,3],[1,2]]
So it seems what you want is all pairs of products from the list:
ghci> :m +Data.List
ghci> [ a * b | a:bs <- tails [2, 3, 5, 587], b <- bs ]
[6,10,1174,15,1761,2935]
But you also want the inital numbers:
ghci> [ a * b | a:bs <- tails [2, 3, 5, 587], b <- 1:bs ]
[2,6,10,1174,3,15,1761,5,2935,587]
This uses a list comprehension, but this could also be done with regular list operations:
ghci> concatMap (\a:bs -> a : map (a*) bs) . init $ tails [2, 3, 5, 587]
[2,6,10,1174,3,15,1761,5,2935,587]
The latter is a little easier to explain:
Data.List.tails produces all the suffixes of a list:
ghci> tails [2, 3, 5, 587]
[[2,3,5,587],[3,5,587],[5,587],[587],[]]
Prelude.init drops the last element from a list. Here I use it to drop the empty suffix, since processing that causes an error in the next step.
ghci> init [[2,3,5,587],[3,5,587],[5,587],[587],[]]
[[2,3,5,587],[3,5,587],[5,587],[587]]
ghci> init $ tails [2, 3, 5, 587]
[[2,3,5,587],[3,5,587],[5,587],[587]]
Prelude.concatMap runs a function over each element of a list, and combines the results into a flattened list. So
ghci> concatMap (\a -> replicate a a) [1,2,3]
[1, 2, 2, 3, 3, 3]
\(a:bs) -> a : map (a*) bs does a couple things.
I pattern match on my argument, asserting that it matches an list with at least one element (which is why I dropped the empty list with init) and stuffs the initial element into a and the later elements into bs.
This produces a list that has the same first element as the argument a:, but
Multiplies each of the later elements by a (map (a*) bs).
You can get the suffixes of a list using Data.List.tails.
This gives you a list of lists, you can then do the inner multiplications you want on this list with a function like:
prodAll [] = []
prodAll (h:t) = h:(map (* h) $ t)
You can then map this function over each inner list and concatenate the results:
f :: Num a => [a] -> [a]
f = concat . map prodAll . tails
I've been trying to wrap my head around this for a while now, but it seems like my lack of Haskell experience just won't get me through it. I couldn't find a similar question here on Stackoverflow (most of them are related to merging all sublists, without any condition)
So here it goes. Let's say I have a list of lists like this:
[[1, 2, 3], [3, 5, 6], [20, 21, 22]]
Is there an efficient way to merge lists if some sort of condition is true? Let's say I need to merge lists that share at least one element. In case of example, result would be:
[[1, 2, 3, 3, 5, 6], [20, 21, 22]]
Another example (when all lists can be merged):
[[1, 2], [2, 3], [3, 4]]
And it's result:
[[1, 2, 2, 3, 3, 4]]
Thanks for your help!
I don't know what to say about efficiency, but we can break down what's going on and get several different functionalities at least. Particular functionalities might be optimizable, but it's important to clarify exactly what's needed.
Let me rephrase the question: For some set X, some binary relation R, and some binary operation +, produce a set Q = {x+y | x in X, y in X, xRy}. So for your example, we might have X being some set of lists, R being "xRy if and only if there's at least one element in both x and y", and + being ++.
A naive implementation might just copy the set-builder notation itself
shareElement :: Eq a => [a] -> [a] -> Bool
shareElement xs ys = or [x == y | x <- xs, y <- ys]
v1 :: (a -> a -> Bool) -> (a -> a -> b) -> [a] -> [b]
v1 (?) (<>) xs = [x <> y | x <- xs, y <- xs, x ? y]
then p = v1 shareElement (++) :: Eq a => [[a]] -> [[a]] might achieve what you want. Except it probably doesn't.
Prelude> p [[1], [1]]
[[1,1],[1,1],[1,1],[1,1]]
The most obvious problem is that we get four copies: two from merging the lists with themselves, two from merging the lists with each other "in both directions". The problem occurs because List isn't the same as Set so we can't kill uniques. Of course, that's an easy fix, we'll just use Set everywhere
import Data.Set as Set
v2 :: (a -> a -> Bool) -> (a -> a -> b) -> Set.Set a -> Set.Set b
v2 (?) (<>) = Set.fromList . v1 (?) (<>) . Set.toList
So we can try again, p = v2 (shareElementonSet.toList) Set.union with
Prelude Set> p $ Set.fromList $ map Set.fromList [[1,2], [2,1]]
fromList [fromList [1,2]]
which seems to work. Note that we have to "go through" List because Set can't be made an instance of Monad or Applicative due to its Ord constraint.
I'd also note that there's a lot of lost behavior in Set. For instance, we fight either throwing away order information in the list or having to handle both x <> y and y <> x when our relation is symmetric.
Some more convenient versions can be written like
v3 :: Monoid a => (a -> a -> Bool) -> [a] -> [a]
v3 r = v2 r mappend
and more efficient ones can be built if we assume that the relationship is, say, an equality relation since then instead of having an O(n^2) operation we can do it in O(nd) where d is the number of partitions (cosets) of the relation.
Generally, it's a really interesting problem.
I just happened to write something similar here: Finding blocks in arrays
You can just modify it so (although I'm not too sure about the efficiency):
import Data.List (delete, intersect)
example1 = [[1, 2, 3], [3, 5, 6], [20, 21, 22]]
example2 = [[1, 2], [2, 3], [3, 4]]
objects zs = map concat . solve zs $ [] where
areConnected x y = not . null . intersect x $ y
solve [] result = result
solve (x:xs) result =
let result' = solve' xs [x]
in solve (foldr delete xs result') (result':result) where
solve' xs result =
let ys = filter (\y -> any (areConnected y) result) xs
in if null ys
then result
else solve' (foldr delete xs ys) (ys ++ result)
OUTPUT:
*Main> objects example1
[[20,21,22],[3,5,6,1,2,3]]
*Main> objects example2
[[3,4,2,3,1,2]]