Skip to content

Instantly share code, notes, and snippets.

@hodzanassredin
Last active January 10, 2016 22:12
Show Gist options
  • Save hodzanassredin/fd6650aee7557ec85d46 to your computer and use it in GitHub Desktop.
Save hodzanassredin/fd6650aee7557ec85d46 to your computer and use it in GitHub Desktop.
fsharp comonad monad isomorphism
module CArray =
type CArray<'a> = CA of 'a array * int
let fmap f (CA(a, i)) = CA(Array.map f a, i)
let extract (CA(a, i)) = a.[i]
let extend f (CA(a, i)) =
let es' = Array.mapi (fun i _ -> f (CA(a,i))) a
in CA(es',i)
module MArray =
type CA<'a> = CA of 'a array * int
type MArray<'a,'r> = CA<'a> -> 'r
let runCA m (CA(arr,i)) =
let r = Array.mapi (fun i _ -> m (CA(arr, i))) arr
CA(r,i)
type MArrayBuilder internal () =
member __.Bind(m : MArray<'a,'r> , f : 'r -> MArray<'a,'r2> ) : MArray<'a,'r2> =
fun c ->
let r = m c
f r c
member __.Return(v) = fun _ -> v
let ma = MArrayBuilder()
let get i' (CA(arr,i)) =
try
arr.[i+i']
with ex ->
0
open MArray
let test =
ma{
let! a = get 1
let! b = get 0
return a + b
}
printfn "%A" << runCA test <| CA([|1; 2; 3; 4; 5; 6; 7; 8; 9; 10|], 0)
//CA ([|3; 5; 7; 9; 11; 13; 15; 17; 19; 10|],0)
let test2 = ma{
let! a = test
let! b = test
return a + b
}
printfn "%A" << runCA test2 <| CA([|1; 2; 3; 4; 5; 6; 7; 8; 9; 10|], 0)
//CA ([|6; 10; 14; 18; 22; 26; 30; 34; 38; 20|],0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment