I have a list of lists like for example
[[1,2,3,5],[24,6,8,2],[2,4,5,6,8]]
The goal is to obtain the list of elements common in all the lists. My approach was to create a function that outputs the common elements in two lists
common :: (Foldable t, Eq a) => [a] -> t a -> [a]
common list1 list2 = [x | x<-list1, elem x list2]
and do the operation recursively on all the elements of [[a]] using a fold operation
main :: IO ()
main = do
--- get the number of lists
q <- readLn :: IO Int
--- get the lists and store in a list of lists
list_of_lists <- map (map (read::String->Int ) . words) <$> replicateM q getLine :: IO [[Int]]
--- process and print the output
putStrLn $ show $ foldl (common) list_of_lists
Unfortunately, this doesn't compile and gives an error
• Ambiguous type variable ‘t1’ arising from a use of ‘common’
prevents the constraint ‘(Foldable t1)’ from being solved.
Probable fix: use a type annotation to specify what ‘t1’ should be.
These potential instances exist:
instance Foldable (Either a) -- Defined in ‘Data.Foldable’
instance Foldable Maybe -- Defined in ‘Data.Foldable’
instance Foldable ((,) a) -- Defined in ‘Data.Foldable’
...plus one other
...plus 26 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the first argument of ‘foldl’, namely ‘(common)’
In the second argument of ‘($)’, namely ‘foldl (common) list_of_lists’
In the second argument of ‘($)’, namely
‘show $ foldl (common) list_of_lists’
I can understand the probable fix lies in how the function common is defined, but couldn't seem to get it, as I am relatively new to Haskell.
You should make use of foldl1, or provide the initial value for the accumulator. foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b expects an initial value as accumulator of type b. With foldl1 :: Foldable t => (a -> a -> a) -> t a -> a, it takes the first element as initial accumulator:
import Control.Monad(replicateM)
main :: IO ()
main = do
q <- readLn :: IO Int
list_of_lists <- replicateM q (map read . words <$> getLine) :: IO [[Int]]
print (foldl1 common list_of_lists)
This gives us:
Prelude Control.Monad> main
3
1 2 3 5
24 6 8 2
2 4 5 6 8
[2]
The above function will error if the list of items is empty. So here q should, like @JosephSible says, be strictly greater than zero.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With