hedgehogqa / haskell-hedgehog-classes

Hedgehog will eat your typeclass bugs
BSD 3-Clause "New" or "Revised" License
57 stars 17 forks source link

How could monadIOLaws ever be used? #12

Open ocharles opened 5 years ago

ocharles commented 5 years ago

To have a law-abiding MonadIO means that your monad must be at least as powerful as IO - ie, be a transformer over IO. Such a monad won't have a meaningful Eq instance, because IO has no Eq instance. Can monadIOLaws actually ever be used?

chessai commented 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)

ocharles commented 5 years ago

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.

chessai commented 5 years ago
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

ocharles commented 5 years ago

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.

chessai commented 5 years ago

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.

chessai commented 1 year ago

I think it should be removed.