PureScript и классы типов
У меня проблемы с классами типов PureScript. Я должен сказать заранее, что я тоже не эксперт по Haskell, поэтому приношу свои извинения, если это очевидные ошибки.
Я попробовал несколько разных подходов и ударил стену для каждого. Я в основном пытаюсь определить 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 на примере. Я не смог понять это.
Спасибо за любую помощь.
1 ответ
На самом деле, вы были почти там с первой попытки, проблема у вас здесь Edge
это конструктор данных с одним полем, содержащим объект, тогда как тот же синтаксис в Haskell определяет функции для доступа к нескольким полям в ваших данных.
У Haskell нет объектов / записей в качестве объектов первого класса, как это делает PureScript, поэтому все, что вам нужно сделать, это развернуть объект из вашего Edge
:
show (Edge e) = "Edge from " ++ show e.from ++ " to " ++ show e.to