Haskell экзистенциальные типы - PullRequest
8 голосов
/ 13 августа 2011

Я пытаюсь обернуть свой мозг вокруг экзистенциальных типов Хаскелла, и мой первый пример - это разнородный список вещей, которые можно показать:

{-# LANGUAGE ExistentialQuantification #-}
data Showable = forall a. Show a => Showable a

showableList :: [Showable]
showableList = [Showable "frodo", Showable 1]

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

instance Show Showable where
  show a = ...

Проблема, с которой я столкнулся, заключается в том, что я действительно хочу сделать здесьвызовите базовую реализацию a *1009* show .Но я испытываю затруднения, ссылаясь на это:

instance Show Showable where
  show a = show a

выбирает Показываемый метод показа на RHS, который работает в кругах.Я попытался автоматически получить Show, но это не работает:

data Showable = forall a. Show a => Showable a
  deriving Show

дает мне:

Can't make a derived instance of `Show Showable':
  Constructor `Showable' does not have a Haskell-98 type
  Possible fix: use a standalone deriving declaration instead
In the data type declaration for `Showable'

Я ищу способ вызвать базовую реализацию Show :: showтак что Показываемое не должно заново изобретать колесо.

1 Ответ

17 голосов
/ 13 августа 2011
instance Show Showable where
   show (Showable a) = show a

show a = show a не работает, как вы поняли, потому что он повторяется бесконечно.Если мы попробуем это без экзистенциальных типов, мы увидим ту же проблему и решение

data D = D Int
instance Show D where show a = show a -- obviously not going to work

instance Show D where show (D a) = "D " ++ (show a) -- we have to pull out the underlying value to work with it
...