Is there a type class for boring types?

Or, alternatively, some common class that lets me express that a type is boring (i.e., inhabited by precisely one fully-defined value)? lens has Settable, whose law ensures the type involved has a boring representation (in the sense of representable functor), but is there a more fundamental way? class Boring x where inhabitant :: x instance Boring () where inhabitant = () instance Boring (Proxy a) where inhabitant = Proxy instance Boring y => Boring (x -> y) where inhabitant = const inhabitant instance (Boring x, Boring y) => Boring (x, y) where inhabitant = (inhabitant, inhabitant) instance Boring x => Boring (Const x y) where inhabitant = Const inhabitant instance Boring x => Boring (Identity x) where inhabitant = Identity inhabitant ...

Seems a bit of an ad hoc class, but maybe
class (Bounded a, Eq a) => Singular a where
singular :: a
With the constraint that singular = maxBound = minBound. Not going to let
you write an instance for (->) though, but maybe there are other ways to
get that with a different property.
On Tue, Feb 2, 2016 at 5:42 PM David Feuer
Or, alternatively, some common class that lets me express that a type is boring (i.e., inhabited by precisely one fully-defined value)? lens has Settable, whose law ensures the type involved has a boring representation (in the sense of representable functor), but is there a more fundamental way?
class Boring x where inhabitant :: x instance Boring () where inhabitant = () instance Boring (Proxy a) where inhabitant = Proxy instance Boring y => Boring (x -> y) where inhabitant = const inhabitant instance (Boring x, Boring y) => Boring (x, y) where inhabitant = (inhabitant, inhabitant) instance Boring x => Boring (Const x y) where inhabitant = Const inhabitant instance Boring x => Boring (Identity x) where inhabitant = Identity inhabitant ... _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

I suspect there are a lot of classes that are almost right - and they might
even be better suited to a particular application than the more generic
solutions.
The most striking for me is Monoid. 'inhabitant' looks like 'mempty', while
'mappend' would simply be (\_ _ -> inhabitant). What's more, almost all
instances you mention are already instances of Monoid, so less work for
you. Also note that there is no way to ensure that only "truly boring"
classes will be made instances of your class, so maybe relying on Monoid is
enough?
Another class that comes to mind is
class Unit m where unit :: m ()
which is one of the fundamental classes of the functor hierarchy. (Note
that pure x == fmap (const x) unit). Granted, it's of a different kind,
but...
Just this weekend I have been working on a polykinded class:
class Reducible target r where reduce :: Proxy r -> target
which can be seen as a generalization of Boring, Unit, Typeable, and heaps
of other stuff. So there is probably no end to how fundamental you can be.
Am 02.02.2016 18:41 schrieb "David Feuer"
Or, alternatively, some common class that lets me express that a type is boring (i.e., inhabited by precisely one fully-defined value)? lens has Settable, whose law ensures the type involved has a boring representation (in the sense of representable functor), but is there a more fundamental way?
class Boring x where inhabitant :: x instance Boring () where inhabitant = () instance Boring (Proxy a) where inhabitant = Proxy instance Boring y => Boring (x -> y) where inhabitant = const inhabitant instance (Boring x, Boring y) => Boring (x, y) where inhabitant = (inhabitant, inhabitant) instance Boring x => Boring (Const x y) where inhabitant = Const inhabitant instance Boring x => Boring (Identity x) where inhabitant = Identity inhabitant ...
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

Because Monoid has the unfortunate instance
instance Monoid m => Monoid (a -> m)
this would work (without, of course, giving me the law I want). But the
uniqueness of the inhabitant is the real point, and there doesn't seem to
be any way to enforce that except by a stated law.
On Feb 2, 2016 2:16 PM, "insanemole ."
I suspect there are a lot of classes that are almost right - and they might even be better suited to a particular application than the more generic solutions.
The most striking for me is Monoid. 'inhabitant' looks like 'mempty', while 'mappend' would simply be (\_ _ -> inhabitant). What's more, almost all instances you mention are already instances of Monoid, so less work for you. Also note that there is no way to ensure that only "truly boring" classes will be made instances of your class, so maybe relying on Monoid is enough?
Another class that comes to mind is class Unit m where unit :: m () which is one of the fundamental classes of the functor hierarchy. (Note that pure x == fmap (const x) unit). Granted, it's of a different kind, but... Just this weekend I have been working on a polykinded class: class Reducible target r where reduce :: Proxy r -> target which can be seen as a generalization of Boring, Unit, Typeable, and heaps of other stuff. So there is probably no end to how fundamental you can be. Am 02.02.2016 18:41 schrieb "David Feuer"
: Or, alternatively, some common class that lets me express that a type is boring (i.e., inhabited by precisely one fully-defined value)? lens has Settable, whose law ensures the type involved has a boring representation (in the sense of representable functor), but is there a more fundamental way?
class Boring x where inhabitant :: x instance Boring () where inhabitant = () instance Boring (Proxy a) where inhabitant = Proxy instance Boring y => Boring (x -> y) where inhabitant = const inhabitant instance (Boring x, Boring y) => Boring (x, y) where inhabitant = (inhabitant, inhabitant) instance Boring x => Boring (Const x y) where inhabitant = Const inhabitant instance Boring x => Boring (Identity x) where inhabitant = Identity inhabitant ...
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

On Tue, Feb 02, 2016 at 12:41:34PM -0500, David Feuer wrote:
Or, alternatively, some common class that lets me express that a type is boring (i.e., inhabited by precisely one fully-defined value)?
FWIW it's the dual of Empty: https://hackage.haskell.org/package/total-1.0.4/docs/Lens-Family-Total.html

Indeed! Empty is lucky. The existence, for a type x, of a function impossible :: forall y . x -> y is sufficient--parametricity guarantees uniqueness. For Boring/Singular, this is certainly not the case. Non-boring types y typically have multiple functions possible :: forall x . x -> y We'd really want sole :: Pi (y :: a) -> inhabitant = y For some horrifyingly vague notion of equality. That obviously isn't going to cut it for real Haskell. On Feb 2, 2016 4:34 PM, "Tom Ellis" < tom-lists-haskell-cafe-2013@jaguarpaw.co.uk> wrote:
On Tue, Feb 02, 2016 at 12:41:34PM -0500, David Feuer wrote:
Or, alternatively, some common class that lets me express that a type is boring (i.e., inhabited by precisely one fully-defined value)?
FWIW it's the dual of Empty:
https://hackage.haskell.org/package/total-1.0.4/docs/Lens-Family-Total.html _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
participants (4)
-
David Feuer
-
insanemole .
-
Oliver Charles
-
Tom Ellis