Skip to content

Instantly share code, notes, and snippets.

@gusty
Last active August 29, 2015 14:01
Show Gist options
  • Save gusty/db59b8ad482bdc44ca56 to your computer and use it in GitHub Desktop.
Save gusty/db59b8ad482bdc44ca56 to your computer and use it in GitHub Desktop.
Solve stack overflow in zipIndex function.
#r @"c:/packages/FsControl.1.0.9/lib/net40/FsControl.Core.dll"
open FsControl.Core.TypeMethods
open FsControl.Core.Types
open FsControl.Operators
type MonadBuilder() =
member inline b.Return(x) = result x
member inline b.Bind(p,rest) = p >>= rest
member b.Let (p,rest) = rest p
member b.ReturnFrom(expr) = expr
let monad = new MonadBuilder()
let f a :StateT<_,Cont<_,_>> = monad {
let! n = get ()
do! put (n + 1)
return n, a
}
let zipIndex (xs: 'a list) : (int * 'a) list = Cont.run ((StateT.run (traverse f xs)) 0) fst
// or using eval functions
type Cont<'t,'u> with static member eval (Cont x) = x id
type StateT<'t,'u> with static member inline eval (StateT m) s = monad {
let! t = m s
return (fst t)}
let zipIndex' (xs: 'a list) : (int * 'a) list = Cont.eval ((StateT.eval (traverse f xs)) 0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment