separate Zero typeclass from Monoid
Closed this issue · 8 comments
I need Zero but not Semigroup for one of my projects: https://github.com/michaelficarra/purescript-filterable/blob/577b4ef73697c1998219193b728a8b2a724a44a0/src/Data/Filterable.purs
The problem as I see it is that Zero has no laws, so there is no power gained by abstracting over it, since you can't reason about it.
filter could be defined using MonadPlus on the other hand, in a way which does permit equational reasoning:
filter :: forall m a. (MonadPlus m) => (a -> Boolean) -> m a -> m a
filter p xs = do
x <- xs
if p x
then return x
else mzeroIn addition to what @paf31 stated, if you have a monomorphic data type that you want an empty or to filter, there's lens/optic stuff for that.
Also, if you have Foldable and Unfoldable you should be able to define Filterable.
@joneshf A definition like this seems problematic when considering filtering infinite streams. You can only read values from an infinite stream by unconsing, but you can only add values to an infinite stream by appending.
The MonadPlus approach should work with infinite streams, no?
Sure, but I really don't want the Semigroup constraint. It describes a relationship between t a and t a where I want a relationship between t a and a (where t is a Filterable type). I think this is more like some "Consable" abstraction that I have yet to formalise. Should I take this conversation to the mailing list or something instead?
Well, there's also Cons based on optics for this stuff.
Maybe what you can do is keep your Zero and just provide a default instance for Monoid?
Closing this as I realise it does not make sense to separate out MonoidZero (it may be different than FilterZero).