Skip to content

Instantly share code, notes, and snippets.

@dpiponi
Last active June 5, 2018 21:43
Show Gist options
  • Save dpiponi/212471bc3f26a7756ad86c19e8b63cb8 to your computer and use it in GitHub Desktop.
Save dpiponi/212471bc3f26a7756ad86c19e8b63cb8 to your computer and use it in GitHub Desktop.
This code can be used to model very unlikely disruptions to your code,
eg. hits by cosmic rays.
This is the cosmic ray monad:
> data Cosmic a = Cosmic { central::a, side::[a] } deriving Show
Cosmic a b is considered equal to Cosmic a' b' if
a==a' and b is a permutation of b'.
(I could automatically reduce to canonical form but it would clutter things.)
> instance Functor Cosmic where
> fmap f (Cosmic a a') = Cosmic (f a) (fmap f a')
> instance Applicative Cosmic where
> pure a = Cosmic a []
Note the following line is a kind of Leibniz rule.
You apply f to all of as and
apply all of the fs to a.
(Just as when we differentiate xy we multiply x by
derivative of y and add derivative of x times y.)
I could have defined this in terms of >>= below but
it's nice to be explicit.
> Cosmic f fs <*> Cosmic a as = Cosmic (f a) (fmap f as ++ fmap ($ a) fs)
> instance Monad Cosmic where
> return a = pure a
This is, again, a kind of Leibniz rule:
> m >>= f = join (fmap f m) where
> join (Cosmic a as) = Cosmic (central a) (side a ++ map central as)
Se here's a simple program:
> test =
> let f = (+)
> x = 1
> y = 1
> in x `f` y
Now we consider perturbations. A cosmic ray may strike.
If it does, if might switch the (+) to (*).
It might switch either of the 1s to 2, 3, or 4.
But we're taking the view that cosmic rays are incredibly rare
so the Cosmic monad is designed to track the result of only one strike.
> test' = do
> f <- Cosmic (+) [(*)]
> x <- Cosmic 1 [2, 3, 4]
> y <- Cosmic 1 [2, 3, 4]
> return $ x `f` y
> main = do
> print test
> print test'
What this is telling us is that if there is a (small)
probability ε that (+) gets flipped to (*), and that
in addition the first 1 can get flipped to 2, 3, 4,
each with probability ε, and same for the second 1,
then there are 7 possible results besides the main
one and, for example, there's a 2ε chance of the
result being 4. (This happens either as 1+3 or 3+1.
But 2*2 has chance ε³ so to first order we ignore it.)
You can think of test' as being the derivative of test
with respect to these perturbations.
The probability of getting 16, say, is ε³, and that's
considered very unlikely. It would be tracked by the
third term in the Taylor series if we generalised the
above.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment