Skip to content

Instantly share code, notes, and snippets.

@femtomc
Created April 22, 2020 14:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save femtomc/922ec4d563ab66ebd5e5a8273c99f8e5 to your computer and use it in GitHub Desktop.
Save femtomc/922ec4d563ab66ebd5e5a8273c99f8e5 to your computer and use it in GitHub Desktop.
-- Autodiff using algebraic effects
-- Simple reverse mode with a gradient tape
use .base
ability Differentiable where
cos : Float -> Float
sin : Float -> Float
exp : Float -> Float
Tape : List (Float -> Float)
Tape = []
pullback : List (Float -> Float) -> Request Differentiable a -> List (Float -> Float)
pullback l = cases
{ Differentiable.cos x -> k} -> handle
k (Float.cos x)
with pullback (l List.++ [y -> -1.0 * y * Float.sin x])
{ Differentiable.exp x -> k} -> handle
k (Float.exp x)
with pullback (l List.++ [y -> y * Float.exp x])
{ Differentiable.sin x -> k} -> handle
k (Float.sin x)
with pullback (l List.++ [y -> y * Float.cos x])
{ x } -> l List.++ [y -> y * 1.0]
gradient_tape : (Float -> Float) -> Float -> List (Float -> Float)
gradient_tape v x =
handle v x with pullback []
grad : (Float -> Float) -> Float -> Float
grad f x = (foldl (x -> y -> y x) 1.0) (gradient_tape f x)
-- Test!
p : Float -> Float
p x = Differentiable.exp (Differentiable.cos x)
> grad p 5.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment