serokell / universum

:milky_way: Prelude written in @Serokell
MIT License
176 stars 28 forks source link

Fix `bool` so it's not possible to mess up the params #55

Closed ksaric closed 6 years ago

ksaric commented 7 years ago

http://hackage.haskell.org/package/universum-0.4.3/docs/Bool.html https://github.com/serokell/universum/blob/master/src/Bool.hs#L53

Add a newtype wrapper so someone (like me, for example, which wouldn't be surprising at all) doesn't mess up the parameter order.

Something like:

newtype IfYes m = IfYes { getIfYes :: m a }
newtype IfNo m = IfNo { getIfNo :: m a }

Which would make the signature from:

ifM :: Monad m => m Bool -> m a -> m a -> m a

To (I hope this is the correct order):

ifM :: Monad m => m Bool -> IfYes -> IfNo -> m a

Reason why I'm suggesting this is code from Pos.Slotting.Ntp:

ifNtpUsed :: MonadNtpSlotting m => m a -> m a -> m a
ifNtpUsed ifT ifF = askIfNtpUsed >>= bool ifF ifT
chshersh commented 7 years ago

I don't want to admit but I like this proposal... Something inside me struggles with our design choices for universum to not create new abstractions and not reinvent wheels. But I like type safety and explicit things, I don't like bool blindness.

Probably this should look like this:

newtype IfYes    = IfYes { getIfYes  ::   Bool }
newtype IfNo     = IfNo  { getIfNo   ::   Bool }
newtype IfYesM m = IfYes { getIfYesM :: m Bool }
newtype IfNoM  m = IfNo  { getIfNoM  :: m Bool }

Though I'm not sure about bool. bool is like boolean-eliminator. Order of arguments for bool is dictated by order of constructors in Bool. First argument is for first constructor — False, and second — for True. Just like maybe. It's another question how to remember order of constructors for Bool. But I can propose next mnemonic: False has same first letter as First.

chshersh commented 6 years ago

Deprecated in favor of named library: