Как создать экземпляр Read для типа данных в haskell

Итак, у меня есть тип данных

data SomeType a =
    Type a |
    Mix (SomeType a) (SomeType a)

Это мой шоу экземпляр для SomeType

instance (Show a) => Show (SomeType a) where
    show (Type a) = show a
    show (Mix a b) = "(" ++ show a ++ " " ++ show b ++ ")"

Так

Mix (Type 5) (Type 4)

дал бы мне

(5 4)

Теперь я хочу иметь

read "(3 4)" :: SomeType Int 

производить

(3 4)

или же

read "(a b)" :: SomeType Char

производить

(a b)

Я заблудился от того, как использовать класс Read.

1 ответ

Вот пример, основанный на документации, которая должна быть в состоянии проанализировать все, что show рендеринга (при условии, что тип имеет совместимый Read определен экземпляр), то есть read . show должна быть более или менее идентичность:

instance (Read a) => Read (SomeType a) where
    readsPrec d r = readMix r ++ readType r
      where
        readMix = readParen True $ \r -> do
            (v1, r'') <- readsPrec d r
            (v2, r')  <- readsPrec d r''
            return (Mix v1 v2, r')

        readType r = do
            (v, r') <- readsPrec d r
            return (Type v, r')

Таким образом,

> read "(3 4)" :: SomeType Int 
(3 4)
it :: SomeType Int

Но учтите, что для SomeType Char по умолчанию Show экземпляр Char окружает персонажа одинарными кавычками:

> read "('a' ('b' 'c'))" :: SomeType Char
('a' ('b' 'c'))
it :: SomeType Char

надеюсь это поможет

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