I’m trying to understand the following output of PAKCS:

 

test> ((1+1)+)

_impl#+#Prelude.Num#Prelude.Int (1 _impl#+#Prelude.Num#Prelude.Int 1)

test> :t (+) (1+1)

(+) (1+1) :: Num a => a -> a

 

It surprises me that the subexpression 1+1 is not reduced.  The full expression has no normal form because the first occurrence of + cannot be eliminated.  Yet PAKCS seems to treat it as if it was a value.  This makes a certain practical sense in the context of the REPL, but if this is like a value then why is the subexpression not reduced?

 

If I go one step further and apply $!! to force normalization of the partial application, I see that $!! ignores the subexpression 1+1 (trace shown):

 

test> id $!! ((1+1)+)

Call: id $!! (_impl#+#Prelude.Num#Prelude.Int (1 _impl#+#Prelude.Num#Prelude.Int 1))

Call: id (_impl#+#Prelude.Num#Prelude.Int (1 _impl#+#Prelude.Num#Prelude.Int 1))

Exit: id (_impl#+#Prelude.Num#Prelude.Int (1 _impl#+#Prelude.Num#Prelude.Int 1)) (HNF: _impl#+#Prelude.Num#Prelude.Int (1 _impl#+#Prelude.Num#Prelude.Int 1))

Exit: id $!! (_impl#+#Prelude.Num#Prelude.Int (1 _impl#+#Prelude.Num#Prelude.Int 1)) (HNF: _impl#+#Prelude.Num#Prelude.Int (1 _impl#+#Prelude.Num#Prelude.Int 1))

_impl#+#Prelude.Num#Prelude.Int (1 _impl#+#Prelude.Num#Prelude.Int 1)

 

This seems to imply that (1+1)+ is a normal form, which it clearly is not.

 

Is this perhaps some corner that is not well defined, or are there good reasons to NOT reduce an expression such as ((1+1)+) to (2+)?  I can imagine that attaining correct semantics might require this delay if the subexpression is non-deterministic but I’m not entirely convinced. Certainly, it is not obvious to me.

 

And is there some theoretical basis upon which I can understand these seeming quirks?

 

-Andy