2014-10-16 9 views
5

У меня проблемы с классными классами PureScript. Я должен сказать, впереди, что я не эксперт Haskell, так что извиняюсь, если это очевидные ошибки.PureScript и typeclasses

Я пробовал несколько разных подходов и ударил стену для каждого. Я в основном пытаюсь определить функцию show для ребра в графе. Один подход выглядит следующим образом:

module Foo where 

data Edge n = Edge { from :: n, to :: n } 

instance showEdge :: (Show n) => Show (Edge n) where 
    show e = "Edge from "++(show e.from)++" to "++(show e.to) 

e = Edge { from: 1, to: 2 } 

main = show e 

Это дает мне ошибку:

$ psc src/Attempt1.purs 
Error at src/Attempt1.purs line 6, column 27: 
Error in declaration showEdge 
Cannot unify Prim.Object with Foo.Edge. 

Я предполагаю, что это что-то делать с тем фактом, что она Выведение тип e в определении show. Я попытался добавить аннотацию типа, но я получаю ошибку синтаксиса:

module Foo where 

data Edge n = Edge { from :: n, to :: n } 

instance showEdge :: (Show n) => Show (Edge n) where 
    show e :: Edge n 
    show e = "Edge from "++(show e.from)++" to "++(show e.to) 

e = Edge { from: 1, to: 2 } 

main = show e 

Вторая вещь, которую я попытался было это:

module Foo where 

type Edge n = { from :: n, to :: n } 

instance showEdge :: (Show n) => Show (Edge n) where 
    show e = "Edge from "++(show e.from)++" to "++(show e.to) 

e :: Edge Number 
e = { from: 1, to: 2 } 

main = show e 

Это дает мне:

$ psc src/Attempt2.purs 
Error at src/Attempt2.purs line 5, column 1: 
Type synonym instances are disallowed 

Я затем пробовал явно перечислять базовый тип:

module Foo where 

type Edge n = { from :: n, to :: n } 

instance showEdge :: (Show n) => Show { from :: n, to :: n } where 
    show e = "Edge from "++(show e.from)++" to "++(show e.to) 

e :: Edge Number 
e = { from: 1, to: 2 } 

main = show e 

, который дает мне:

$ psc src/Attempt3.purs 
Error at src/Attempt3.purs line 5, column 1: 
Error in type (to :: n, from :: n): 
Type class instance head is invalid. 

Я понятие не имею, что такое «класс типа экземпляр Голова», поэтому у меня некуда идти оттуда.

Все три попытки потерпели неудачу. Вероятно, по совершенно другим причинам. Будучи новым для PureScript, я просто не знаю, в чем проблема. Я пытался следовать примеру различных типов Data.* и читая PureScript по примеру. Я не смог понять это.

Спасибо за любую помощь.

ответ

7

На самом деле, вы были почти там с первой попытки, проблемы вы имеете здесь Edge является конструктором данных с одного поля содержащего объект, в то время как тот же синтаксис, в Haskell является определение функций для доступа к нескольким полям в данные.

Haskell не имеет объектов/записи в качестве первого класса объектов, как PureScript делает, поэтому все, что вам нужно сделать, это разворачивать объект из Edge:

show (Edge e) = "Edge from " ++ show e.from ++ " to " ++ show e.to