Haskell lists also work nicely for nondeterministic computation.
require :: Bool -> [()]
require True = return ()
require False = []
and then express amb-like computations in effectively the same way: sample :: [(Int, Int)]
sample = do
x <- [1,2,3,4,5]
y <- [1,2,3,4,5]
require (x == 2 * y)
return (x, y)
after which the value of sample is [(2,1),(4,2)]. (Also, my require is effectively the same as the guard function found in Control.Monad, specialized for lists.)