Reputation: 19
I'm trying to turn a list of tuples into a single list with only the second value from each tuple.
targets :: [(a,b)] -> [a]
targets (x:xs) = [snd(x)] ++ targets xs
This is what I have so far but it is not working. Any help would be greatly appreciated.
Upvotes: 1
Views: 111
Reputation: 476503
This is a mapping where for each 2-tuple, you take the second element, hence we can use map :: (a -> b) -> [a] -> [b]
:
targets :: [(a,b)] -> [b]
targets = map snd
Notice that the return type is [b]
: a list of b
s, not a
s. Your type for a Graph
however has as type [(Node a, [Int])]
, so you will need to concatenate these lists together.
Upvotes: 1
Reputation: 35482
There are two mistakes in your code. The first of which, GHC will warn you about:
<interactive>:3:30: error:
• Couldn't match type ‘a’ with ‘b’
‘a’ is a rigid type variable bound by
the type signature for:
targets :: forall a b. [(a, b)] -> [a]
at <interactive>:2:1-25
‘b’ is a rigid type variable bound by
the type signature for:
targets :: forall a b. [(a, b)] -> [a]
at <interactive>:2:1-25
Expected type: [b]
Actual type: [a]
The second element of the tuple is of type b
(since you declare the tuple to be (a, b)
), so the resulting array should not be [a]
(what GHC calls the actual type), but it should be [b]
(what GHC calls the expected type). Then, you're also missing a case. What if it's called on the empty array? Then it won't match (x:xs)
, so you should add a special case for that (also remember that every recursive function should have a base case):
targets :: [(a, b)] -> [b]
-- using x:y instead of [x] ++ y since they do the same thing
targets (x:xs) = snd x:targets xs
-- the base case for when nothing matches
targets _ = []
Upvotes: 1