Safe Haskell | None |
---|---|
Language | Haskell2010 |
Represent do/don't, is/isn't, with/without flags with Choice
.
Boolean blindness
refers to the problem that boolean literals on their own aren't very
informative. In any given context, what does True
mean? What does False
mean? Instead of passing arguments of type Bool
to functions, consider
using Choice
.
Choice
is the type of labeled booleans. Use it as follows:
{-# LANGUAGE OverloadedLabels #-} import Data.Choice (Choice, Do, Don't) -- Blocking read: block until N bytes available. -- Non-blocking: return as many bytes as are available. readBytes :: Handle -> Choice "block" -> Int -> IO ByteString readBytes = ... action1 = print =<< readBytes h (Don't #block) 1024
For GHC < 8.0, where overloaded labels are not available, substitute
(Label :: Label "block")
for #block
.
A comment on labels: why use labels? We could as well ask the user to define ad hoc constructors. But unlike constructors, labels are guaranteed to be singletons. That's exactly what we want: a label doesn't carry any runtime information, it's just a type annotation. Better yet, with labels, there is no need to ensure that constructor names are unique, nor to pollute the precious constructor namespace in a large module with many flags.
- data Choice a
- fromBool :: Bool -> Choice a
- toBool :: Choice a -> Bool
- pattern Do :: forall t. Label t -> Choice t
- pattern Don't :: forall t. Label t -> Choice t
- pattern Is :: forall t. Label t -> Choice t
- pattern Isn't :: forall t. Label t -> Choice t
- pattern With :: forall t. Label t -> Choice t
- pattern Without :: forall t. Label t -> Choice t
- data Label a = Label