Подтвердить что ты не робот

Создание экземпляра класса Read type в Haskell для пользовательского типа данных

У меня есть пользовательский тип данных Foo = Foo{ a :: Int, b :: Int}, и я пытаюсь сделать Foo специальным экземпляром чтения. У меня уже есть функция bar :: String -> Foo, и я попытался сделать это:

instance Read (Foo a b) where
    read s = bar s

но я получаю следующую ошибку при загрузке моего файла в GHCi, чтобы проверить его: Fraction.hs:11:1: read' is not a (visible) method of class Read'

Может ли кто-нибудь сказать мне, в чем проблема, и как я могу фактически создать экземпляр этого типа?

4b9b3361

Ответ 1

Read typeclass не объявляет read напрямую; вместо этого он определяет readsPrec, который поддерживает приоритет (это важно, когда read значение целого типа данных с элементами других типов). Определение, которое вы получаете при использовании deriving (Read), выглядит примерно так:

instance (Read a) => Read (Tree a) where

    readsPrec d r =  readParen (d > app_prec)
                     (\r -> [(Leaf m,t) |
                             ("Leaf",s) <- lex r,
                             (m,t) <- readsPrec (app_prec+1) s]) r
                  ++ readParen (d > up_prec)
                     (\r -> [(u:^:v,w) |
                             (u,s) <- readsPrec (up_prec+1) r,
                             (":^:",t) <- lex s,
                             (v,w) <- readsPrec (up_prec+1) t]) r
      where app_prec = 10
            up_prec = 5

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

read определяется в терминах readsPrec и readList (другой метод в read, который по умолчанию используется для каждого типа, кроме Char, где он использовал для чтения [Char] как строку вместо как список Char).

Если стандартного вывода недостаточно, для типа типа yours, который является просто ведром Int, вы можете игнорировать параметр приоритета.

BTW, read и Show довольно медленные; вы можете рассмотреть другие способы ввода/вывода с вашими данными.

Ответ 2

Это потому, что метод класса, который вы, вероятно, захотите реализовать, readsPrec. См. Здесь полную информацию о Read typeclass: http://zvon.org/other/haskell/Outputprelude/Read_c.html

Кстати, вы должны просто использовать автоматический вывод, а компилятор будет создавать эти методы чтения для вас, например:

data Foo = Foo Int Int
           deriving (Read, Show)