パターンガードとGaucheのutil.match

最近のHaskellにはパターンガードというものがあるらしい.

{-# LANGUAGE PatternGuards #-}

addLookup alist x y
    | Just m <- lookup x alist
    , Just n <- lookup y alist
    = m + n
    | otherwise
    = 0

main = print $ addLookup [(1, 2), (3, 4)] 1 3 -- => 6

Gaucheの util.match でどのように書けるか考えてみた.上のコードでは使ってないけど,ガードの後の式から前に束縛した変数が見えるのでそのようにする.

(use util.match)

(define add-assoc
  (match-lambda*
   ((alist x y)
    (match (assoc x alist)
      ((_ . m) (=> next)
       (match (assoc y alist)
         ((_ . n)
          (+ m n))
         (_ (next))))
      (_ 0)))))

(define (main args)
  (print (add-assoc '((1 . 2) (3 . 4)) 1 3))) ; => 6

できたけど今一つな感じ.複数の式に順次マッチさせるだけなら match-let* が使えるけど,あれはマッチに失敗すると例外が飛んでくるのですっきりしない.一旦リストに纏める方法では前の変数が見えない.


何が問題なのだろう.match のネストが簡潔に書けるマクロがあればいいのかなぁ.上記の例だと,match-let* にマッチに失敗した場合が書ければそれだけでかなりすっきりする気もする.
(19:29 コードがおかしかったので修正)