# Writing efficient code in monadic style

**URL:** <https://discourse.julialang.org/t/writing-efficient-code-in-monadic-style/20756>\
**Category:** Performance\
**Created:** [February 13, 2019, 4:45pm UTC](https://discourse.julialang.org/t/writing-efficient-code-in-monadic-style/20756 "2019-02-13T16:45:46Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![jonathan-laurent](https://avatars.discourse-cdn.com/v4/letter/j/ecae2f/32.png) [@jonathan-laurent](https://discourse.julialang.org/u/jonathan-laurent)\
**Post date:** [February 13, 2019, 4:45pm UTC](https://discourse.julialang.org/t/writing-efficient-code-in-monadic-style/20756/1 "2019-02-13T16:45:47Z")

</div>

Hi everyone,  
I have been trying to write some Julia code in monadic style while keeping it as efficient as possible. I am running in a problem that can be illustrated by the following minimal example:

```julia
# Simple implementation of the "list" monad
bind(f, xs) = [e for x in xs for e in f(x)]
ret(x) = [x]

function f()
    bind([0, 1]) do x
    bind([0, 1]) do y
        ret((x, y))
    end end
end
            
@assert f() == [(0, 0), (0, 1), (1, 0), (1, 1)]          
@code_warntype(f()) # Body::Array{_1,1} where _1...

```

Here, I wish that the type system could infer the return type of `f` (namely `Vector{Tuple{Int, Int}}`), which it does not. Note that in the following simpler example, Julia successfully infers the return type of `f2`:

```julia
function f2()
    bind([0, 1]) do x
        ret((x, x))
    end
end
@code_warntype f2() # Body::Array{Tuple{Int64,Int64},1}...

```

Can you see any way I can solve this problem?

**Edit:** I found that it is possible to solve the problem by adding the following type annotations to `f`:

```julia
function f()
    bind([0, 1]) do x
    bind([0, 1]) do y
            ret((x, y))
    end :: Vector{Tuple{Int, Int}} 
    end :: Vector{Tuple{Int, Int}}
end
            
@assert f() == [(0, 0), (0, 1), (1, 0), (1, 1)]          
@code_warntype(f()) # Body::Array{Tuple{Int64,Int64,Int64},1}

```

Any idea why these annotations are needed here?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [February 14, 2019, 7:36am UTC](https://discourse.julialang.org/t/writing-efficient-code-in-monadic-style/20756/2 "2019-02-14T07:36:54Z")

</div>

I think that the type inference fails on the outer generator. You can see this with

```julia
bind(f, xs) = [e for x in xs for e in f(x)]
ret(x) = [x]

function f()
   bind(f_inner, [0, 1])
end

function f_inner(x)
    bind([0, 1]) do y
        ret((x, y))
    end
end

@code_warntype(f()) # Body::Array{_1,1} where _1..
@code_warntype(f_inner(0)) # OK

```

I am not sure that the Julia compiler is ideal for dealing with monad acrobatics, since arrow types are explicitly not included in the language. So perhaps this programming style will lead to difficulties.
