Marcin 'Qrczak' Kowalczyk wrote:
The version with () does less redundant forcing, although the compiler could perhaps optimize them statically.
I did some tests with both versions in GHC on a large binary tree and they appear to have the same performance (even without -O), so I guess GHC does do this. There's another problem with the a->a version, which is that it's never tail recursive, though perhaps GHC's optimizer can fix that as well. I imagine the a->() version is more likely to compile to good code, but it bothered me that it had such a strange type. But a->a isn't the right type either. In fact I think the right type is (a -> exists b. b). This gets us the best of both worlds in efficiency and conciseness/elegance: instance (Force a, Force b) => Force (a,b) where force (x,y) = force x `seq` force y instance Force Int where force x = x Too bad no Haskell implementation supports it. -- Ben