How to pattern match a function in Elixir

I ran into this problem of pattern matching a function when using mox. I wanted to check that a function is injected into another function as a dependency. Here is a simplified example:

test "calls Dependency.do_something with AnotherModule.function/1" do
  Mox.expect(DependencyMock, :do_something, fn ^(&AnotherModule.function/1) -> nil end)

  Module.call()

  Mox.verify!()
end

But this code doesn't work in Elixir:

(CompileError) invalid argument for unary operator ^, expected an existing variable, got: ^(&AnotherModule.function/1)

After some research, I found how to do this correctly in Elixir: Improve error messages for invalid expression in match · Issue #5649 · elixir-lang/elixir

x = &List.first/1
case &List.first/1 do
  ^x -> true
end

So my use case only needs a small fix:

test "calls Dependency.do_something with AnotherModule.function/1" do
  expected_fun = &AnotherModule.function/1
  Mox.expect(DependencyMock, :do_something, fn ^expected_fun -> nil end)

  Module.call()

  Mox.verify!()
end

One caveat is that it doesn't work for anonymous functions even if they have the same body and arity. Because they are completely unrelated and Elixir doesn't know how to check if they can match:

fun1 = fn _ -> nil end
fun2 = fn _ -> nil end

case fun2 do
  ^fun1 -> true
  _ -> false
end
false

Pattern matching is a really useful feature in functional languages. But Elixir's implementation does have some unexpected behaviour. For example:

I guess we need to get used to them for quite some time, because as José Valim explained in that issue: "There is very little interest in making functions valid patterns in Elixir."