Maybeモナド的なパターンはand-let*を使うことで処理することができます。

(define (maybe-add maybe-a maybe-b)
  (and-let* ((a maybe-a)
             (b maybe-b))
           (+ a b)))

(maybe-add 3 2)   ; => 5
(maybe-add #f 5)  ; => #f
(maybe-add 0 #f)  ; => #f
(maybe-add #f #f) ; => #f

リストモナドにおける<-のようなletの亜種は無いのかな、と思って探してみたところ、gauche.generatorにglet*というものがありました。

(define (add-all gxs gys gzs)
  (generate
   (^(yield)
     (glet* ((x (gxs))
             (y (gys))
             (z (gzs)))
       (yield (+ x y z))))))

これを実行すると次のようになります。

(generator->list
 (add-all (list->generator '(1 2 3))
          (list->generator '(0 2 4))
          (list->generator '(5 6 7))))
;; => (6)

…??

どうも、glet*はジェネレーターの先頭の要素を取り出して、その要素に対して処理を行い、eofが来た場合はそのまま終了するというだけの構文のようです。


do-generatorというdolistの仲間のようなものもありましたが、これも一番内側のジェネレーターがeofに達した時点で終了してしまいます。

リストモナド的なことをしたい場合は、自分でどうにかするしかなさそうですね……。