2015-02-14 4 views
1

Я недавно начал изучать Haskell и испытываю трудности с выяснением, что не так с моим кодом, но закончилось неудачей.Не удалось совместить ожидаемый тип с фактическим типом

Это часть моего кода, показывающая, что я объявила конструктор данных для типа Graph, который представляет собой список кортежей значения и список этого значения.

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

Это тип синоним кортежа из двух целых чисел,

type Point = (Int, Int) 

И, наконец, этот код, чтобы найти второй аргумент графа с помощью первого аргумента (т.е. поиска/хеширования значения)

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

Это сообщение об ошибке, которое я получаю при попытке загрузить модуль

hw1.hs: 37: 16: Не удалось совместить ожидаемый тип «Графическая точка» с фактическим типом '[(Точка, [Точка])]' В шаблоне: x: xs В уравнении для ' pointNeighbor ': pointNeighbor (х: хз) точка = если FST х == точка, то SND х еще pointNeighbor (хз) указывают

hw1.hs: 37: 79: не могли соответствовать ожидается тип Graph Пойнт ' с фактическим типом' [(Точка, [Точка])] ' В первом аргументе' pointNeighbor ', а именно' (xs) ' В выражении: pointNeighbor (xs) point

Похоже, что точка графа должна быть распознана как [(Point, [Point])], но, по-видимому, она дает мне эту ошибку, и я не могу найти какое-либо решение в Интернете.

Заранее спасибо :)

ответ

2

Ваша функция ожидает, что первый аргумент будет типа Graph. Как определено Graph, существует только один способ сделать это: с помощью конструктора значений Graph (вхождение слова 'Graph' на правой стороне в определении data).

Однако матч шаблона, который вы пытаетесь выполнить притворяется, как первый аргумент прост List, вместо List, которые были сделаны частью конструкторы по Graph значения.

матч Узор должен быть для (Graph (x:xs)), а также рекурсивный вызов в предложении else следует использовать (Graph xs) так:

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

Заметим также, что вы не определить базовый случай, когда список пуст.

+0

Спасибо, я понимаю лучше :) Я также заметил, что я должен исправить (хз) часть в (Graph (xs)) тоже. – MazaYong

2

Поскольку Graph является конструктором данных, вы должны соответствовать шаблону против него:

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

Я просто понял, что мое решение, как и ваше, нуждается в другом использовании «Графа» вокруг рекурсивного вызова «pointNeighbor» в предложении 'else' ... (Graph xs)' или рекурсивный вызов будет иметь ту же участь как оригинал OP. – ely

+0

@ Mr.F Спасибо за указание. – ThreeFx

+0

Спасибо, теперь я понимаю это лучше :) – MazaYong

Смежные вопросы