## Choose a random item from a list in one pass

Adapted from here.

```
{-# LANGUAGE BangPatterns #-}
module Choose where
import System.Random
import GHC.Base (oneShot)
choose :: (Foldable f, RandomGen g) => f a -> g -> (Maybe a, g)
choose xs = foldr f (const (,)) xs (0 :: Integer) Nothing
where
f x a = oneShot (\ !c m g -> case m of
Nothing -> a 1 (Just x) g
Just y -> case randomR (0,c) g of
(0,g') -> a (c+1) (Just x) g'
(_,g') -> a (c+1) (Just y) g')
{-# INLINE f #-}
```