view 7-Haskell/cointoss.hs @ 103:98be775c533c default tip

An odd "non-determinism" example from StackOverflow It is clever, but doesn't make much sense as to how it gets its results
author IBBoard <dev@ibboard.co.uk>
date Sun, 14 Jul 2019 13:44:13 +0100
parents
children
line wrap: on
line source

module CoinToss where
    -- Based on https://stackoverflow.com/questions/20638893/how-can-non-determinism-be-modeled-with-a-list-monad
    -- Because it only throws "*** Exception: <interactive>:57:1-26: Non-exhaustive patterns in function toss" in gchi
    import Control.Monad -- Required for guard, but not mentioned in the example

    data CoinType = Fair | Biased deriving (Show)
    data Coin = Head | Tail deriving (Eq,Show)

    toss Fair   = [Head, Tail]
    toss Biased = [Head, Head]

    pick = [Fair, Biased]

    experiment = do
        coin   <- pick         -- Pick a coin at random (Non-determinism takes both coins)
        result <- toss coin    -- Toss it, to get a result (Non-determinism joins all possible toss results in a single list)
        guard (result == Head) -- We only care about results that come up Heads (Non-determinism does something weird and inexplicable)
        return coin            -- Return which coin was used in this case (Magic has happened here and we've suddenly gone from "Head, Tail, Head, Head" to "Fair, Biased, Biased")

    part_experiment = do
        coin   <- pick         -- Pick a coin at random
        result <- toss coin    -- Toss it, to get a result
        return result          -- Return the intermediary results

    part_experiment_2 = do
        coin   <- pick         -- Pick a coin at random
        result <- toss coin    -- Toss it, to get a result
        return guard (result == Head)          -- Return the intermediary results
    
    -- Load the module and then run "experiment" and you get [Fair,Biased,Biased], which apparently shows that there's a 2/3 chance it's a biased coin