summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorPéter Diviánszky <divipp@gmail.com>2016-04-07 11:57:23 +0200
committerPéter Diviánszky <divipp@gmail.com>2016-04-07 11:57:23 +0200
commit1fb8403f0c3f56ddcc61f467e47dd8722ac55293 (patch)
treeff2388df7262af73ccd0a565b4808b5324c3db6a /doc
parent685fbe269923cfc0202975505fffbdca0479a065 (diff)
more documentation on pattern match compilation
Diffstat (limited to 'doc')
-rw-r--r--doc/guide.pandoc155
1 files changed, 114 insertions, 41 deletions
diff --git a/doc/guide.pandoc b/doc/guide.pandoc
index 64774eba..4fba4fe0 100644
--- a/doc/guide.pandoc
+++ b/doc/guide.pandoc
@@ -320,61 +320,77 @@ Design decisions:
320 320
321### Pattern guard trees 321### Pattern guard trees
322 322
323Pattern guard trees is the simplest data structure which is general enough to express all pattern match related syntactic structures. 323Pattern guard trees is an intermediate representation to which all pattern match related syntactic structures are transformed.
324 324
325First we give a syntax of pattern guards trees which is used only in this documentation: 325Syntax of pattern guards trees (used only in this documentation):
326 326
327----------- -- -------------------------------------------------------- ----------------------- 327----------- -- ---------------------------------------------------------- -----------------------
328*guardtree* := *expression* **guard tree leaf** 328*guardtree* := *expression* **rhs**
329 | *guardtree* `|` *guardtree* **alternative patterns** 329 | *guardtree* `|` *guardtree* **alternative patterns**
330 | *conname* (*parpat*)* `<-` *expression* `->` *guardtree* **pattern guard** 330 | `MatchFailure`
331 | `let` *bindings* `in` *guardtree* **let binding** 331 | *pattern* `<-` *expression* `,` *guardtree* **pattern guard**
332*parpat* := *pattern* 332 | `let` *bindings* `in` *guardtree* **let binding**
333 | *parpat* `,` *parpat* **parallel patterns** 333----------- -- ---------------------------------------------------------- -----------------------
334*pattern* := *variable* **variable pattern**
335 | *conname* (*parpat*)* **constructor pattern**
336 | *expression* -> *parpat* **view pattern**
337 | *parpat* `::` *expression* **type annotation**
338----------- -- -------------------------------------------------------- -----------------------
339 334
340Remarks: 335Remarks:
341 336
342- A guard tree is an expression (it may appear whereever an expression may appear) 337- Pattern guard trees are generalizations of [pattern guards](https://wiki.haskell.org/Pattern_guard):
338 - pattern guard trees are expressions (may appear whereever an expression may appear)
339 - pattern guard trees may have alternatives not only on the top level
340 For example, in `[] <- x, (Nothing <- y, ... | True <- z, ...)` both alternatives will match only if `x` is an empty list.
341 - pattern guard trees may have let bindings not only on the top level
342- Pattern guard trees form a monoid with alternative patterns and `MatchFailure`.
343 343
344Examples: 344Examples:
345 345
3461. definition of `not` with pattern guard trees: 3461. Definition of `not` with pattern guard trees:
347
348 ~~~~~ {.haskell}
349 not x = (True <- x, False) | (False <- x, True)
350 ~~~~~
351
3522. Definition of `zip`:
353
354 ~~~~~ {.haskell}
355 zip [] _ = []
356 zip x [] = []
357 zip (a:as) (b:bs) = (a,b) : zip as bs
358 ~~~~~
359
360 A possible translation to pattern guard trees:
347 361
348 ~~~~~ {.haskell} 362 ~~~~~ {.haskell}
349 not x = (True <- x -> False) | (False <- x -> True) 363 zip v0 v1
364 = ([] <- v0, [])
365 | (let x = v0 in [] <- v1, [])
366 | ((:) a as <- v0, (:) b bs <- v1, (a, b): zip as bs)
350 ~~~~~ 367 ~~~~~
351 368
352The semantics of pattern guard trees is given by the `value`, `matchesP` and `matches` functions (pseudo code): 369#### Semantics
370
371The semantics of pattern guard trees is given by the `value` function:
372(This is pseudo code, it could be turned into a valid function producing a template Haskell splice):
353 373
354~~~~~ {.haskell} 374~~~~~ {.haskell}
355value :: GuardTree a -> Maybe a 375value :: GuardTree a -> Maybe a
356value (Leaf e) = Just e 376value (Leaf e) = Just e
357value (Alt x y) = value x <> value y 377value (Alt x y) = value x <|> value y
358value (Let bs x) = value (let bs in x) 378value MatchFailure = Nothing
359value (PatternGuard cn ps e x) = case PCon cn ps `matches` e of 379value (Let bs x) = value (let $bs in x)
360 Just bs -> value (let bs in x) 380value (PatternGuard p e x) = case matchPattern p e of
361 Nothing -> Nothing 381 Just bs -> value (let $bs in x)
362 382 _ -> Nothing
363matchesP :: ParPat a -> a -> Maybe [Binding] 383
364Pat x `matchesP` v = x `matches' v 384matchPattern :: Pattern a -> Expression a -> Maybe Bindings
365ParPat x y `matchesP` v = case x `matchesP` v of 385...
366 Just bs -> case let bs in y `matchesP` v of 386
367 Just bs' -> Just (bs ++ bs') 387data GuardTree a where
368 Nothing -> Nothing 388 Leaf :: Expression a -> GuardTree a
369 Nothing -> Nothing 389 Alt :: GuardTree a -> GuardTree a -> GuardTree a
370 390 MatchFailure :: GuardTree a
371matches :: Pattern a -> a -> Maybe [Binding] 391 -- bindings are not strongly typed here for simplicity
372Var n `matches` v = Just [n = v] 392 Let :: Bindings -> GuardTree a -> GuardTree a
373PCon cn ps `matches` v = case v of 393 PatternGuard :: Pattern b -> Expression b -> GuardTree a -> GuardTree a
374 cn vs -> mconcat (sequence (zipWith matchesP ps vs))
375 _ -> Nothing
376ViewPat f p `matches` v = p `matches` f v
377TypeAnn p t `matches` v = p `matches` v
378~~~~~ 394~~~~~
379 395
380 396
@@ -382,14 +398,71 @@ TypeAnn p t `matches` v = p `matches` v
382 398
383#### Function alternatives 399#### Function alternatives
384 400
4011. make n fresh variables v1, ..., vn where n is the arity of the function
4022. the new left hand side is `f` v1 ... vn
4033. translate each function alternative to a pattern guard tree with the help of v1, ..., vn
4044. compose the pattern guard trees with alternative patterns to get the new right hand side
405
406Example:
407
408~~~~~ {.haskell}
409zip [] _ = []
410zip x [] = []
411zip (a:as) (b:bs) = (a,b) : zip as bs
412~~~~~
413
414Transformed code:
385 415
416~~~~~ {.haskell}
417zip v0 v1
418 = ([] <- v0, _ <- v1, [])
419 | (x <- v0, [] <- v1, [])
420 | (a:as <- v0, b:bs <- v1, (a,b) : zip as bs)
421~~~~~
386 422
387 423
388#### View patterns 424#### View patterns
389 425
390 426
427### Normalization of pattern guard trees
428
429The normal form of pattern guard trees contains only simple constructor patterns:
430
431------------- -- ---------------------------------------------------------- -----------------------
432*conpattern* := *conname* (*variable*)*
433------------- -- ---------------------------------------------------------- -----------------------
434
435The normalization process is driven by the shape of patterns:
436
437
438pattern shape input output
439-------------- ---------------------------- -- --------
440wildcard `_` `<-` e `,` t ~> t
441variable v `<-` e `,` t ~> `let` v = e `in` t
442at-pattern v`@`p `<-` e `,` t ~> `let` v = e `in` p `<-` v `,` t
443nested pattern C p1 ... pn `<-` e `,` t ~> C w1 ... wn `<-` e `,` p1 `<-` w1 `,` ... `,` pn `<-` wn `,` t
444view pattern (f `->` p) `<-` e `,` t ~> p `<-` f e `,` t
445-------------- ---------------------------- -- --------
446
447
391### Compilation of pattern guard trees 448### Compilation of pattern guard trees
392 449
450#### Filtering
451
452Filtering is a transformation on pattern guard trees, given an expession and a constructor name:
453
454~~~~~ {.haskell}
455filterTree :: Expression b -> Expression b -> GuardTree a -> GuardTree a
456filterTree _ _ (Leaf e) = Leaf e
457filterTree e a (Alt x y) = filterTree e a x <> filterTree e a y
458filterTree e a MatchFailure = MatchFailure
459filterTree e a (Let bs t) = Let bs (filterTree e a t)
460filterTree e a@(Con c es) (PatternGuard (PCon c' vs) e' t)
461 | e /= e' = PatternGuard (PCon c' vs) e' (filterTree e a t)
462 | c /= c' = Nothing
463 | otherwise = filterTree e a (let $(bind vs es) t)
464~~~~~
465
393 466
394### TODO 467### TODO
395 468