Hi George,
I didn't have access to my computer over the weekend, so I apologize for not actually running the examples I provided. I was simply projecting what I thought could reasonably be assumed about the behavior of a Set. Data.Set.Monad's departure from those assumptions is a double-edged sword, and so I'd just like to clarify a couple things.
Regarding antisymmetry, if I also define
instance Ord Foo where
(==) = (==) `on` a
then would that count as satisfying the law?
In any event, I find it an amusing coincidence that Data.Set.Monoid does essentially the same thing as Foo: it retains some extra information, and provides an Eq instance that asserts equality modulo dropping the extra information.
So I have a question and a concern. Loading this file into ghci: hpaste.org/70245
ghci> foo1 == foosTransform1
True
ghci> foo2 == foosTransform2
False
given x == y, where x and y are Sets, we cannot guarantee that fmap f x == fmap f y, due to the extra information retained for the sake of obeying functor laws.
My question is this: how does the library manage to obey functor laws?
My concern is this: the aforementioned behavior should be clearly documented in the haddocks. Presumably, people will not know about the extra information being retained. The following, out of context (where most debugging happens), could be quite confusing:
ghci> foosTransform1
fromList [Foo {a = 1, b = 4}]
ghci> fmap restoreA foosTransform1
fromList [Foo {a = 1, b = 1},Foo {a = 2, b = 2},Foo {a = 3, b = 3},Foo {a = 4, b = 4}]
The data seems to pop out of nowhere. Even if Ord instances like the one for Foo shouldn't exist, they almost certainly will anyways, because the Haskell type system doesn't prevent them. Users of the library should be informed accordingly.
Dan Burton
801-513-1596
Hi Dan,
Thanks for your feedback and your question regarding the functor laws.
Please try your example in GHCi and/or evaluate it by hand. The
library does not violate the functor laws.
I committed quick check properties for functor laws, as well as, laws
for other type classes to the repo. You can give it a try. It is also
possible, with a little bit of effort, to prove those properties by
hand.
Speaking of laws, BTW, your contrived Ord instance violates one of the
Ord laws. The documentation for Ord says that: "The Ord class is used
for totally ordered datatypes". Your definition violates the
antisymmetry law [1]:
If a <= b and b <= a then a == b
by reporting two elements that are not equal as equal.
Cheers, George
[1] http://en.wikipedia.org/wiki/Totally_ordered