| Safe Haskell | None | 
|---|---|
| Language | Haskell2010 | 
Decidable
Contents
Decidable
class Divisible f => Decidable (f :: * -> *) where #
A Decidable contravariant functor is the contravariant analogue of Alternative.
Noting the superclass constraint that f must also be Divisible, a Decidable
 functor has the ability to "fan out" input, under the intuition that contravariant
 functors consume input.
In the dicussion for Divisible, an example was demonstrated with Serializers,
 that turn as into ByteStrings. Divisible allowed us to serialize the product
 of multiple values by concatenation. By making our Serializer also Decidable-
 we now have the ability to serialize the sum of multiple values - for example
 different constructors in an ADT.
Consider serializing arbitrary identifiers that can be either Strings or Ints:
data Identifier = StringId String | IntId Int
We know we have serializers for Strings and Ints, but how do we combine them
 into a Serializer for Identifier? Essentially, our Serializer needs to
 scrutinise the incoming value and choose how to serialize it:
identifier :: Serializer Identifier
identifier = Serializer $ identifier ->
  case identifier of
    StringId s -> runSerializer string s
    IntId i -> runSerializer int i
It is exactly this notion of choice that Decidable encodes. Hence if we add
 an instance of Decidable for Serializer...
instance Decidable Serializer where
  lose f = Serializer $ a -> absurd (f a)
  choose split l r = Serializer $ a ->
    either (runSerializer l) (runSerializer r) (split a)
Then our identifier Serializer is
identifier :: Serializer Identifier identifier = choose toEither string int where toEither (StringId s) = Left s toEither (IntId i) = Right i
Methods
Acts as identity to choose.
Instances
contramany :: Decidable f => f a -> f [a] #