5

I'm writing a piece of Haskell code that uses the abstraction of Traversable. Behind this abstraction I want to be able to conceal all regular traversable structures like lists, trees, maps etc, with special case of Data.Functor.Identity.Identity as an elementary structure containing single value. I would also want to cover a case of an "empty" structure. Does such "empty" traversable instance exist? Maybe it is already provided by any library?

My first (and maybe naive) attempt to define such instance would be as follows. Does it make sense?

data Empty a = Empty

instance Functor Empty where
    fmap _ _ = Empty

instance Foldable Empty where
    foldr _ init _ = init

instance Traversable Empty where
    sequenceA _ = pure Empty
  • 2
    Minor point: note that "empty" might be a misleading name, since there is a value for `Empty a`, namely `Empty`. Someone could instead expect that an empty type has no (non bottom) values, like `Void` in the libraries, or like (using a GHC extension) `data Empty a` without any constructor. – chi Apr 29 '19 at 09:47

1 Answers1

13

As far as types in base go, Proxy is precisely that. Const () would also work. (There is also U1, but that is part of the generics machinery, and might feel a tad out of place in other contexts.)

duplode
  • 33,731
  • 7
  • 79
  • 150
  • thanks, that's exactly what I was looking for, its implementation is the same as mine, good to know it's already there in base. – Eryk Ciepiela Apr 28 '19 at 19:32
  • @ErykCiepiela `Proxy` is often used to allow the caller to "pass a type" to a function. E.g. if `f :: SomeClass a => Proxy a -> Int` the caller can choose `a` using something like `f (Proxy :: Proxy Bool)`. Without the proxy argument, the type become ambiguous and is rejected (well, now GHC can also allow those, and I actually prefer ambiguous types + type arguments as a style, but let's neglect that). If that's your intent behind `Empty a`, use `Proxy` instead. Otherwise, `Const ()` may be more appropriate to signal your intent (hard to tell, though). – chi Apr 29 '19 at 09:53
  • @chi I wondered about how natural using `Proxy` in this case would feel, too, but then I saw [this comment by Edward Kmett](https://www.reddit.com/r/haskell/comments/47uquu/comment/d0g69bn), which gave me enough confidence to mention it here. – duplode Apr 29 '19 at 10:40