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.zigans...@gmail.com _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe