1

In Haskell, is there any way to declare function it behaves differently depending on whether the type of a argument is an instance of specific type class? For example, can I define genericShow in the following example?

-- If type `a` is an instance of `Show`.
genericShow :: Show a => a -> String
genericShow = show
-- If type `a` is not an instance of `Show`.
genericShow :: a -> String
genericShow _ = "(Cannot be shown)"

> genericShow 3
"3"
> genericShow const
"(Cannot be shown)"
user3749167
  • 161
  • 6
  • 6
    (1) Closely related: [*Check whether a type is an instance of Show in Haskell?*](https://stackoverflow.com/q/35785176/2751851); [*Use specialized implementation if a class instance is available*](https://stackoverflow.com/q/44250854/2751851). I'm not closing against those now because I'm not sure about which kind of answer would best fit here. (2) In the context of those two questions, [the *constraints-emerge* package](http://hackage.haskell.org/package/constraints-emerge) is also worth a shout. (3) In any case, as those discussions suggest, this isn't something to be undertaken lightly. – duplode Nov 19 '18 at 02:35
  • It helps me. Thanks a lot! – user3749167 Nov 19 '18 at 09:27

1 Answers1

1

No.

The closest you can get is to use Overlapping instances, with a catch-all instance for anything not having a more specific Show instance.

instance {-# OVERLAPPABLE #-} Show a  where
  show _ = "(Cannot be shown)"

Overlapping instances come with lots of caveats: see topics like 'orphan instances', 'Incoherent instances'. That's particularly awkward with Prelude classes like Show, because there's likely to be lots of instances hidden away in libraries.

As @duplode says, there are many dangers. Almost certainly there's a better way to achieve whatever it is you think you want.

AntC
  • 2,623
  • 1
  • 13
  • 20