1
votes

I've recently started learning Haskell and is having trouble figuring out what is wrong with my code but ended up in failure.

This is part of my code showing that I've declared data Constructor for Graph type, which is a list of tuple of a value and a list of that value.

data Graph a = Graph [(a,[a])] deriving (Ord, Eq, Show)

This is type synonym for tuple of two ints,

type Point = (Int, Int)

And finally this code is to find second argument of a graph using first argument(i.e searching / hashing value)

pointNeighbor :: Graph Point -> Point -> [Point]
pointNeighbor (x:xs) point = if fst x == point then snd x else pointNeighbor (xs) point

This is the error message I get when I try to load module

hw1.hs:37:16: Couldn't match expected type ‘Graph Point’ with actual type ‘[(Point, [Point])]’ In the pattern: x : xs In an equation for ‘pointNeighbor’: pointNeighbor (x : xs) point = if fst x == point then snd x else pointNeighbor (xs) point

hw1.hs:37:79: Couldn't match expected type ‘Graph Point’ with actual type ‘[(Point, [Point])]’ In the first argument of ‘pointNeighbor’, namely ‘(xs)’ In the expression: pointNeighbor (xs) point

It seems like Graph Point should be recognized as [(Point,[Point])] but apparently it is giving me this error and I can't find any solution on web.

Thanks in advance :)

2

2 Answers

2
votes

Your function expects the first argument to be of type Graph. As Graph is defined, there is only one way to do this: with the Graph value constructor (the ocurrence of the word 'Graph' on the right hand side of the = in the data definition).

However, the pattern match you are trying to perform pretends like the first argument is plain List, instead of a List that has been made part of the Graph value constructor.

The pattern match should be for (Graph (x:xs)) and also the recursive call in the else clause should use (Graph xs) like this:

pointNeighbor :: Graph Point -> Point -> [Point]
pointNeighbor (Graph (x:xs)) point = 
    if fst x == point 
        then snd x 
        else pointNeighbor (Graph xs) point

Note also that you don't define a base case when the list is empty.

2
votes

Because Graph is a data constructor, you have to pattern match against it:

pointNeighbor :: Graph Point -> Point -> [Point]
pointNeighbor (Graph (x:xs)) point = if fst x == point then snd x else pointNeighbor (Graph xs) point
               ^^^^^                                                                  ^^^^^