Funct symClosure issue - haskell

I'm not sure what this error message wants me to change as I can't see the issue with my code but clearly there's something wrong otherwise it would compile.
Error message:
* Couldn't match expected type `(a, a)' with actual type `[(a, a)]'
* In the expression: xs ++ (flips xs)
In the expression: [xs ++ (flips xs)]
In an equation for `symClosure': symClosure xs = [xs ++ (flips xs)]
* Relevant bindings include
xs :: [(a, a)]
symClosure :: [(a, a)] -> [(a, a)]
symClosure xs = [xs ++ (flips xs)]
Code:
heads :: (Eq a) => [(a,a)] -> [a]
heads xs = [x | (x, _) <- xs]
tails :: (Eq a) => [(a,a)] -> [a]
tails xs = [x | (_,x) <- xs]
flips :: [a] -> [(a,a)]
flips xs = tails xs ++ heads xs
symClosure :: (Eq a) => [(a,a)] -> [(a,a)]
symClosure xs = [xs ++ (flips xs)]
Side note: I can't import anything and I can't change signatures.
Again, any info to help me understand is very much appreciated :)

I think your flips does not do what its signature says it does:
heads :: (Eq a) => [(a,a)] -> [a]
tails :: (Eq a) => [(a,a)] -> [a]
(++) :: [a] -> [a] -> [a]
in other words, with your definition this signature is correct:
flips :: [(a, a)] -> [a]
flips xs = tails xs ++ heads xs
Note that you can only call tails and heads on lists of pairs. Also note you can leave out the Eq constraint from all the signatures above.
If you meant to reverse the tuples, you can use zip instead
flips :: [(a, a)] -> [(a, a)]
flips xs = tails xs `zip` heads xs
As for symClosure, taking the definition of flips above, the expression
symClosure xs = [xs ++ (flips xs)]
would produce a list with a single element, itself a list of pairs. That explains why it is saying that the (a, a) in your signature does not match the [(a, a)] it infers from the expression. You probably need to leave the brackets out.
symClosure xs = xs ++ flips xs

Related

Debugging type Errors in Haskell

I'm trying to write a function, returning all permutations from a list in Haskell:
perms :: [a] -> [[a]]
perms [] = [[]]
perms xs = map (\y -> concat_each y (perms (list_without y xs))) xs
list_without :: (Eq a) => a -> [a] -> [a]
list_without x xs =
filter (\y -> not (y==x)) xs
concat_each :: a -> [[a]] -> [[a]]
concat_each x xs =
map (\y -> x:y) xs
What I think happens in line3:
y is a and x is [a], so
list_without y xs is [a].
perms (list_without ...) is thus [[a]]
so concat_each y (perms ...) gets a and [[a]], resulting in [[a]]
So the function for map is a -> [[a]] and everything should be okay.
But the compiler seems to see things differently:
Couldn't match type `a' with `[a]'
`a' is a rigid type variable bound by
the type signature for perms :: [a] -> [[a]]
at C:\Users\Philipp\Desktop\permutations.hs:1:10
Expected type: [a]
Actual type: [[a]]
Relevant bindings include
y :: a (bound at permutations.hs:3:18)
xs :: [a] (bound at permutations.hs:3:7)
perms :: [a] -> [[a]]
(bound at permutations.hs:2:1)
In the expression: concat_each y (perms (list_without y xs))
In the first argument of `map', namely
`(\ y -> concat_each y (perms (list_without y xs)))'
How would I debug this error message properly? I don't really know where to start checking my types.
map :: (x -> y) -> [x] -> [y]
The first argument you gave to map has type a -> [[a]], i.e., x = a and y = [[a]] so
:: [x] -> [ y ]
map (\y -> ...) :: [a] -> [[[a]]]
-- ^ ^^^^^
-- x = a, y = [[a]]
In this case, the result of that map (\y -> ...) xs is a list where each element corresponds to the permutations starting with a fixed element y in xs. In the end, you don't care which element a permutation starts with; you can forget that separation using concat:
perms = concat (map (\y -> ...) xs)
-- or
perms = concatMap (\y -> ...) xs
-- or
perms = xs >>= \y -> ...

Reflexive Closure

I have been working on a question about reflexive closure:
The reflexive closure of a relation R is the smallest relation bigger than R which is reflexive. In other words, it is R with whatever pairs added to make R reflexive. Write a function (reflClosure) which takes a list of pairs (standing for R) and returns a list of pairs which is the reflexive closure of R. You do not need to worry about the order in which pairs appear in your return value.
I came up with this solution but it seems quite sloppy and lack neatness.
-- QUESTION 2: Functions and relations
reflClosure :: (Eq a) => [(a,a)] -> [(a,a)]
reflClosure (x:xs) = nub ( (x:xs) ++ [ (x,x) | x <- (heads (x:xs)) ++ (tails
(x:xs)) ])
nub :: Eq a => [a] -> [a]
nub = nubBy (==)
nubBy :: (a -> a -> Bool) -> [a] -> [a]
nubBy eq [] = []
nubBy eq (x:xs) = x : nubBy eq (filter (\y -> not (eq x y)) xs)
heads :: (Eq a) => [(a,a)] -> [a]
heads list = nub [x | (x, _) <- list]
tails :: (Eq a) => [(a,a)] -> [a]
tails list = nub [x | (_,x) <- list]
exists :: (Eq a) => (a,a) -> [(a,a)] -> Bool
exists x xs = length (filter (==x) xs) > 0
-- TEST SET FOR Q2
{-
Your functions should have the following behaviour:
reflClosure [(1,2),(3,2)] = [(1,2),(3,2),(1,1),(2,2),(3,3)]
reflClosure [(1,1),(3,5)] = [(1,1),(3,5),(3,3),(5,5)]
DO NOT WORRY ABOUT THE ORDER IN WHICH PAIRS APPEAR IN YOUR LIST
-}
Is there an easier way to do this? Explanation would be incredibly useful to learn from as well.
A nicer way to write heads and tails is the following:
heads :: (Eq a) => [(a,a)] -> [a]
heads = nub . map fst
tails :: (Eq a) => [(a,a)] -> [a]
tails = nub . map snd
It's point-free, plus it uses the more "functional" map rather than a list comprehension.
However, the fact that you need both means there's an even nicer way:
(heads (x:xs), tails (x:xs)) = (\(a,b) -> (nub a) (nub b)) $ unzip (x:xs)
Getting the fsts and the snds is equivalent to an unzip.
Also, you can simplify the signature of exists:
exists :: (Eq a) => a -> [a] -> Bool
exists x xs = length (filter (==x) xs) > 0
since nothing depends on the input being a list of pairs.
Data.List already defines nubBy, so I'm not sure why you've defined it there.
It's not clear why you've defined reflClosure to match on (x:xs), because all you care about (apparently) is that the list is non-empty. Perhaps something like this:
reflClosure :: (Eq a) => [(a,a)] -> [(a,a)]
reflClosure [] = []
reflClosure xs =
let (as,bs) = unzip xs
in nub $ xs ++ [ (x,x) | x <- (nub as) ++ (nub bs) ]
Relations are isomorphic to sets of pairs, not lists of pairs, so it makes sense to model them as such. Note that all the Ord constraints below are there because the implementation of Set needs it.
Use the standard library sets because they are fast.
import Data.Set (Set)
import qualified Data.Set as Set
A type synonym to make the code easier to read:
-- A relation with underlying set s
type Relation s = Set (s,s)
Now we can write a function that gets all the members of the underlying set:
underlyingMembers :: Ord a => Relation a -> Set a
underlyingMembers r = (Set.map fst r) `Set.union` (Set.map snd r)
Once we have that, finding the reflexive closure of a relation is easy:
reflexiveClosure :: Ord a => Relation a -> Relation a
reflexiveClosure r = r `Set.union` (Set.map (\x -> (x,x)) (underlyingMembers r)
If you really need to work with lists, (you really shouldn't, though) you can fromList/toList:
listVersion :: Ord a => [(a,a)] -> [(a,a)]
listVersion = Set.toList . reflexiveClosure . Set.fromList
If any of this is unclear, please leave a comment and I will explain more in detail.

Haskell add to list in list

i have the following code
groupEq :: Eq a => [a] -> [[a]]
groupEq list = foldl (\acc x -> if (isType acc x) then ((last acc) ++ [x]) else acc++[[x]]) [] list
isType :: Eq a => [[a]] -> a -> Bool
isType list item
| (length list) == 0 = False
| head (last list) == item = True
| otherwise = False
Now, i am having difficulties understanding why it would not compile.
The problem is with the ((last acc) ++ [x]) part of it. I understand it as it takes the last element of accumulator, which would be [[a]] at this point and tries to add an element to it.
The idea what i want to achieve is this:
-- groupEq [1,2,2,3,3,3,4,1,1] ==> [[1], [2,2], [3,3,3], [4], [1,1]]
Full error is
Couldn't match type ‘a’ with ‘[a]’
‘a’ is a rigid type variable bound by
the type signature for groupEq :: Eq a => [a] -> [[a]]
at exam_revisited.hs:3:12
Expected type: [[[a]]]
Actual type: [[a]]
Relevant bindings include
x :: a (bound at exam_revisited.hs:4:28)
acc :: [[a]] (bound at exam_revisited.hs:4:24)
list :: [a] (bound at exam_revisited.hs:4:9)
groupEq :: [a] -> [[a]] (bound at exam_revisited.hs:4:1)
In the first argument of ‘last’, namely ‘acc’
In the first argument of ‘(++)’, namely ‘(last acc)’
What am i missing here?
groupEq is declared to return [[a]], but ((last acc) ++ [x]) is of type [a].
A quick and dirty solution is to change this expression into
init acc ++ [last acc ++ [x]].

Haskell, type matching problems

I cannot understand why the function:
repli :: [a] -> Int -> [a]
repli xs n = concatMap (replicate n) xs
cannot be rewritten as:
repli :: [a] -> Int -> [a]
repli [] _ = []
repli (x:xs) n = (take n $ repeat x) : repli xs n
or
repli :: [a] -> Int -> [a]
repli [] _ = []
repli (x:xs) n = (replicate n x) : repli xs n
Ghci complains:
Couldn't match expected type ‘a’ with actual type ‘[a]’
‘a’ is a rigid type variable bound by
the type signature for repli :: [a] -> Int -> [a]
at 99questions.hs:41:10
Relevant bindings include
xs :: [a] (bound at 99questions.hs:43:10)
x :: a (bound at 99questions.hs:43:8)
repli :: [a] -> Int -> [a] (bound at 99questions.hs:42:1)
In the first argument of ‘(:)’, namely ‘(replicate n x)’
In the expression: (replicate n x) : repli xs n
I don't understand why, since doing all the type computations it turns out ok. repeat x is [a] and so take n is [a]. Therefore it shouldn't complain.
The signature of (:) is a -> [a] -> [a]. Therefore, you cannot have lists on both sides of the operator. That's the cause of your error.
You could instead use (++), which has the signature [a] -> [a] -> [a].

Haskell "Couldn't match expected type ‘a’ with actual type ‘[a0]’"

Im doing a project in Haskell where I am trying to create a function which takes two list inputs and then returns a union of the list but without any duplicates.
The problem is that I keep getting the error message:
Couldn't match expected type ‘a’ with actual type ‘[t0]’
‘a’ is a rigid type variable bound by
the type signature for newList :: [a] -> [a] -> [a]
Here is my code:
allList :: (Eq a) => [a] -> [a] -> [a]
allList [] [] = []
allList x y = (x ++ y)
checkDup [] = []
checkDup (z:zs)
| z `elem` zs = checkDup zs
| otherwise = z : checkDup zs
newList :: (Eq a) => [a] -> [a] -> [a]
newList [] [] = []
newList x y = [checkDup z | z <- allList x y]
The first allList function creates a list of the two list, the checkDup creates a new list without any duplicates and the newList uses list comprehension to pass the combined list to the checkDup.
Anyone know where I am going wrong?
The problem lies here:
newList x y = [checkDup z | z <- allList x y]
z is supposed to be a list you pass to checkDup, but in this case, z is just a single element
Maybe you want:
newList x y = checkDup $ allList x y
newList can be declared as follows:
newList :: (Eq a) => [a] -> [a] -> [a]
newList = checkDup . allList
Since #Smac89 answered your question, why not use a data representation like Data.Set?
import qualified Data.Set as S
allList :: Ord a => [a] -> [a] -> [a]
allList xs ys = S.toList $ S.union (S.fromList xs) (S.fromList ys)
(although the continued use of Sets is probably even more meaningful.)
Or by using Data.List:
import Data.List
newList :: Eq a => [a] -> [a] -> [a]
newList xs ys = nub $ xs ++ ys

Resources