In Haskell, equality test is normally performed using ==
coming the Eq
class. This function is (in most cases) defined under pure Haskell terms, so it follows all consequences of applying it recursively to big data structures. Therefore, a seemingly trivial comparison can take significant amount of time. Come on, this should be instant (reminder about laziness):
ghci> let x = [1..100000000] in x == x
True
(2.81 secs, 14,400,130,800 bytes)
Why doesn't Haskell use comparison by reference here? Does Haskell even allow me to do so if I really want to?
CodePudding user response:
Short answer: No this isn't possible in Haskell, and for very good reasons. Referential equality is a fundamental part of the language design, and preserving it makes Haskell distinct from many other languages in the language design space.
A slightly longer answer: This is a well-studied topic, typically referred to as observable sharing, dating back to at least early 2000s:
Claessen and Sands explain cases in which cases Observable Sharing is useful and how it can be incorporated into the language. This is a very easy to read paper which explains the issue in detail and suggests a non-conservative extension. Good for understanding the basic problems.
Gill's solution to this problem is a very viable approach that is used in practice, called type-safe observable sharing. The idea here is that you can create equalities in pure code, but you can only observe them in the monadic IO context; which preserves referential equality. It has no false negatives, and very few false positives. There is also an implementation of this idea on hackage that you can readily use.
Long story short: No, you cannot do referential-equality, or pointer-equality, or directly observe sharing in Haskell for very good reasons. The problem is well studied and understood, and there are practical solutions to address the issue in the Haskell ecosystem without breaking referential transparency.