Open ocharles opened 5 years ago
This is true. However, orphan instances are often common in test suites. That, or a newtype around the transformer which is given an Eq instance. One could use unsafePerformIO here, which is safe here (not generally, but in the case of running tests with hedgehog-classes it should be)
But my point is you can't write an Eq
instance because there's no way to compare IO
. So even if you newtype
a transformer over IO
, there's still not going to be an Eq
instance.
newtype EqIO a = EqIO (IO a)
instance Eq a => Eq (EqIO a) where
EqIO x == EqIO y = unsafePerformIO $ do
xVal <- x
yVal <- y
pure $ x == y
This is what I was suggesting
Ok, but now your Eq
instance doesn't pass the Eq
laws (tryReadTMVar foo
where foo
is non-empty will reduce to Just x == Nothing
, so reflexivity doesn't hold). Something just feels off here, I'm just trying to see what the actual value in this is.
That makes sense. That Eq instance is pretty lousy in lots of concurrent/asynchronous/transactional situations. I'm not really sure if it (monadIOLaws) should be removed, because you could be testing types that don't include any such computations. At the very least this should be documented, at worst monadIOLaws should be removed.
I think it should be removed.
To have a law-abiding
MonadIO
means that your monad must be at least as powerful asIO
- ie, be a transformer overIO
. Such a monad won't have a meaningfulEq
instance, becauseIO
has noEq
instance. CanmonadIOLaws
actually ever be used?