
Hello Eric, You can't tell; the head not withstanding, `[a]` is still a lazy list, so you would need to look at the function body to see if any extra forcing goes on. `Force` does not induce `seq`ing: it is an obligation for the call-site. (Added it to the FAQ). Edward Excerpts from Eric Seidel's message of 2015-09-04 09:06:15 -0700:
Another good example would be
foo :: ![Int] -> ![Int]
Does this force just the first constructor or the whole spine? My guess would be the latter.
On Fri, Sep 4, 2015, at 08:43, Edward Z. Yang wrote:
Excerpts from Eric Seidel's message of 2015-09-04 08:29:59 -0700:
You mention NFData in the motivation but then say that !Maybe !Int is not allowed. This leads me to wonder what the semantics of
foo :: !Maybe Int -> !Maybe Int foo x = x
bar = foo (Just undefined)
are. Based on the FAQ it sounds like foo would *not* force the undefined, is that correct?
Yes. So maybe NFData is a *bad* example!
Also, there's a clear connection between these UnliftedTypes and BangPatterns, but as I understand it the ! is essentially a new type constructor. So while
foo1 :: !Int -> !Int foo1 x = x
and
foo2 :: Int -> Int foo2 !x = x
have the same runtime behavior, they have different types, so you can't pass a regular Int to foo1. Is that desirable?
Yes. Actually, you have a good point that we'd like to have functions 'force :: Int -> !Int' and 'suspend :: !Int -> Int'. Unfortunately, we can't generate 'Coercible' instances for these types unless Coercible becomes polykinded. Perhaps we can make a new type class, or just magic polymorphic functions.
Edward