[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