Continuation Monad (2)

[Haskell] Continuation Monad (1) [id:yts:20050102#p2] の続き。

13.2 Escaping continuations

Example
(define list-product
  (lambda (s)
    (call/cc
      (lambda (exit)
        (let recur ((s s))
          (if (null? s) 1
              (if (= (car s) 0) (exit 0)
                  (* (car s) (recur (cdr s))))))))))
list_product :: Num a => [a] -> Cont r a
list_product = \s -> callCC (\exit ->
      fix (\recur s -> 
              if null s then 1
                else  if head s == 0 then exit 0
                  else  return (head s) * recur (tail s)) s)
*Main> runCont (list_product [3,4,1,2,5]) id
120
*Main> runCont (list_product $ [3,4,1,2,5,0] ++ [1..]) id
0

Haskellらしい解法。

list_product_lazy :: Num a => [a] -> a
list_product_lazy [] = 1
list_product_lazy (0:_) = 0
list_product_lazy (x:xs) = x * list_product_lazy xs
*Main> list_product_lazy [3,4,1,2,5]
120
*Main> list_product_lazy $ [3,4,1,2,5,0] ++ [1..]
0