> Why Haskell is so? Why  case  zipRem undefined []
>                         of
>                           (ps,xs',ys') -> ((x,y):ps, xs', ys')
> 
> does not allow the result of           zipRem undefined []
> to be of                               (ps,xs',ys')
> (which type is declared in  zipRem) ?
> And `let', `where' do allow this.
> 
> Now, the simpler example:
>   f []     = []
>   f (x:xs) = case  f xs  of  ps -> (x,x):ps
> 
>   head $ f (1:undefined) --> (1,1)
> 
> Here `case' behaves differently. I am about totally confused.
> The past century was not enough to study the basic Haskell.
> Maybe, the constructor (,,) in the zipRem pattern forces some kind
> of strictness, I do not know.

This is a consequence of the semantics of pattern matching (consult the
Haskell Report). EVERY type in Haskell has _|_ (bottom = undefined;
think 
about this definition: x=x) as one of its elements, including the tuple 
types (([a],[a],[a]), for example). But when you ask in a case
expression 
that certain expression e SHOULD have the form (ps,xs',ys'), the
compiler
should COMPUTE e until it founds the tuple constructor; as the rule to
compute bottom is x=x, then that computation is also undefined. That's
for

  let undef = undef
   in case undef of
        (ps,xs',ys') -> 1:ps
  ~
  _|_

In the simpler case of case e of ps -> ..., the variable ps always
succeed, and then 

  let undef = undef
   in case undef of
        ps -> 1:ps
   ~
   1:undef

If you change the cases by wheres, as in 

  f = 1:ps
   where (ps,xs',ys') = undef

the where part is not computed UNTIL you need ps, and then f is
equivalent to 1:undef. The case expression FORCES the computation of e,
while the where does not (let neither).
It's clear now?
Fidel.

Reply via email to