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

Другие вопросы по тегам