[Haskell-cafe] About the lazy pattern

Bulat Ziganshin bulat.ziganshin at gmail.com
Wed May 27 16:03:43 EDT 2009


Hello 张旭,

Wednesday, May 27, 2009, 11:51:34 PM, you wrote:

> Hi, I am really new to haskell. I am reading "A gentle instruction
> to haskell" now. And I just cannot understand the chapter below. Is
> there anybody who can gives me some hints about why the pattern
> matching for "client" is so early?

because it assumes that there are may be *multiple* lines defining
client and therefore to start "executing" right part of equation it
should ensure that left side is correct. with lazy patterns, you
effectively disable multi-equation definitions:

length ~(x:xs) = 1+length xs
length [] = 0  -- this line never used!

lazy patter is exactly equivalent to using one variable and `let` to
further parse data:

length xxs = let x:xs=xxs in 1+length xs


> How does the pattern matching works here?
>  Thank you so much for answering my questions!
>  ?
>  Sincerely, 
>  nemo
>  
> 4.4??Lazy Patterns
>  There is one other kind of pattern allowed in Haskell. It is
> called a lazy pattern, and has the form ~pat. Lazy patterns are
> irrefutable: matching a value v against ~pat always succeeds,
> regardless of pat. Operationally speaking, if an identifier in pat
> is later "used" on the right-hand-side, it will be bound to that
> portion of the value that would result if v were to successfully match pat, and _|_ otherwise.
> Lazy patterns are useful in contexts where infinite data structures
> are being defined recursively. For example, infinite lists are an
> excellent vehicle for writing simulation programs, and in this
> context the infinite lists are often called streams. Consider the
> simple case of simulating the interactions between a server process
> server and a client process client, where client sends a sequence of
> requests to server, and server replies to each request with some
> kind of response. This situation is shown pictorially in Figure 2.
> (Note that client also takes an initial message as argument.)  
>   
> Figure 2
> Using streams to simulate the message sequences, the Haskell code
> corresponding to this diagram is: 

> reqs?????????????????????=?client?init?resps
> resps????????????????????=?server?reqs

> These recursive equations are a direct lexical transliteration of the diagram.
> Let us further assume that the structure of the server and client look something like this:

> client?init?(resp:resps)?=?init?:?client?(next?resp)?resps
> server??????(req:reqs)???=?process?req?:?server?reqs

> where we assume that next is a function that, given a response from
> the server, determines the next request, and process is a function
> that processes a request from the client, returning an appropriate response.
> Unfortunately, this program has a serious problem: it will not
> produce any output! The problem is that client, as used in the
> recursive setting of reqs and resps, attempts a match on the
> response list before it has submitted its first request! In other
> words, the pattern matching is being done "too early." One way to
> fix this is to redefine client as follows: 

> client?init?resps?????????=?init?:?client?(next?(head?resps))?(tail resps)

> Although workable, this solution does not read as well as that
> given earlier. A better solution is to use a lazy pattern: 

> client?init?~(resp:resps)?=?init?:?client?(next?resp)?resps

> Because lazy pat  terns are irrefutable, the match will immediately
> succeed, allowing the initial request to be "submitted", in turn
> allowing the first response to be generated; the engine is now
> "primed", and the recursion takes care of the rest.
>  ?


> 使用新一代 Windows Live Messenger 轻松交流和共享! 立刻下载!
>   


-- 
Best regards,
 Bulat                            mailto:Bulat.Ziganshin at gmail.com



More information about the Haskell-Cafe mailing list