Вернуть `show a` if (Show a) существует, в противном случае его представление типа if (Typeable a) - PullRequest
0 голосов
/ 27 августа 2018

Я хотел бы написать

class Described a where
  describe :: a -> String

instance {-# OVERLAPPING #-} (Show a) => Described a where
  describe = show

instance {-# OVERLAPPABLE #-} (Typeable a) => Described a where
  describe = show . typeOf

Это не сработает, потому что правая сторона каждого экземпляра одинакова. Я подумал, что это можно решить, взглянув на https://wiki.haskell.org/GHC/AdvancedOverlap, но мне кажется, что мне нужно определить экземпляры для многих существующих типов, чтобы заставить любое из этих решений работать. Каково было бы лучшее решение здесь?

1 Ответ

0 голосов
/ 27 августа 2018

Стандартный прием для выбора экземпляра - создать новый тип. Итак:

newtype DescribeViaTypeable a = DVT a
newtype DescribeViaShow     a = DVS a

instance Show     a => Described (DescribeViaShow     a) where describe (DVS x) = show x
instance Typeable a => Described (DescribeViaTypeable a) where describe (DVT x) = show (typeOf x)

Теперь вызывающие абоненты могут выбирать, какое описание им нравится, если оба доступны, и типы данных могут быть явными о том, какое описание они ожидают получить для своих полей, устраняя любую магию.

...