> I agree that it would be interesting to learn what non-strong monads look like.
A monad is strong if:
- its underlying functor is strong
- the strength commutes with the monad unit `return :: a -> m a`, i.e. `return (x,y) === strength x (return y)`
- the strength commutes with the monad multiplication `join :: m (m a) -> m a`, i.e. `strength x (join mmy) === join (map strength (strength x mmy))`
So a non-strong monad is one for which at least one of these conditions is false.
Non-strong functors are easy to find examples of: take any container type with multiple "slots" (e.g. lists, arrays, n>1-tuples) and put it in a language with linear types. You can't implement `strength` for these types because you can't necessarily copy the `x` value.
Off the top of my head, I can't think of any non-contrived way to violate the latter two conditions without also breaking the monad laws or the requirements of a monoidal product, but presumably they're out there.
A monad is strong if:
- its underlying functor is strong
- the strength commutes with the monad unit `return :: a -> m a`, i.e. `return (x,y) === strength x (return y)`
- the strength commutes with the monad multiplication `join :: m (m a) -> m a`, i.e. `strength x (join mmy) === join (map strength (strength x mmy))`
So a non-strong monad is one for which at least one of these conditions is false.
Non-strong functors are easy to find examples of: take any container type with multiple "slots" (e.g. lists, arrays, n>1-tuples) and put it in a language with linear types. You can't implement `strength` for these types because you can't necessarily copy the `x` value.
Off the top of my head, I can't think of any non-contrived way to violate the latter two conditions without also breaking the monad laws or the requirements of a monoidal product, but presumably they're out there.