How to encode the monadic value in an elixir?

So, I'm trying to better understand the idea of โ€‹โ€‹monads. And I'm trying to start simple; which creates a very simple Elixir module with a return function. It:

defmodule MonadTest do
   def return(s), do: fn s -> s end
end

      

Then I bind the function to a variable like this:

f = &MonadTest.return/1

      

Then I try to call the function like this:

f.(12)

      

But instead of going back, I get a function. Like this:

iex(22)> r = f.(12)
#Function<0.122071921/1 in MonadTest.return/1>
iex(23)> r
#Function<0.122071921/1 in MonadTest.return/1>

      

I'm sure I'm missing something obvious - but what am I missing here?

+3


source to share


1 answer


A monad is a way of describing how operations are related to each other.

The most common form of monad is passing the result from one function to the next function in the chain. Elixir provides a pipe operator for this |>

. However:

Based on the OP and not wanting to change the arity:

The original parameter passed to a named function is never used. If you want to preserve the arity of a named function, but want the value to be returned by an anonymous chaining function, you could implement a non-anonymous function as such:

  defmodule MonadTest do
    def return(s), do: fn -> s end
  end
  f = MonadTest.return(1)
  f.()

      

alternatively, you can use the function anonymously, as you did in your post:

  defmodule MonadTest do
    def return(s), do: fn -> s end
  end
  f = &MonadTest.return/1
  f.(1).()

      




I think there are two things here that we can clarify. (1) is the syntax &<NamedFunction>/<arity>

and the second is parameter passing.

The syntax &MonadTest.return/1

will generate an anonymous function with the same named function definition MonadTest.return

.

This is typically used when passing a named function as a parameter, for example if you need to use MonadTest.return / 1 in an enumerated method such as Enum.map (1..5, and MonadTest.return / 1).

In my example, I will not pass a parameter to a named function, since you are passing it to an anonymous function inside the newly defined MonadTest.return / 0.

For your purposes, you probably don't need to generate an anonymous function, and can instead refer to a named function directly:

  defmodule MonadTest do
    def return, do: fn s -> s end
  end
  f = MonadTest.return
  f.(12)

      

If you need MonadTest to be anonymous, you need to call it and then pass the parameter to the anonymous function nested inside.

  defmodule MonadTest do
    def return, do: fn s -> s end
  end
  f = &MonadTest.return/0
  f.().(12)

      

+7


source







All Articles