# Pattern matching a struct on a map via a pinned variable

``````defmodule Foo do
defstruct [:foo]
end

%{foo: "foo"} = %Foo{foo: "foo"} # Works

foo = %{foo: "foo"}
^foo = %Foo{foo: "foo"} # Fails with "** (MatchError) no match of right hand side value: %Foo{foo: "foo"}"
``````

Is this expected?

The doc says:

`iex> ^x = 2`

Because we have pinned `x` when it was bound to the value of `1` , it is equivalent to the following:

`iex> 1 = 2`

I guess this is not the same thing when a map is on the left side.

It is the same thing, but youâ€™re mixing up values and patterns. `^` is not a pattern substitution operator. It binds a value inside a pattern and always checks for exact equality. It happens in the case of simple integers that the value `1` and the pattern `1` are equal. In case of lists however `[1 | rest]` is a valid pattern but if you had:

``````iex(1)> rest = [2,3]
[2, 3]
iex(2)> list = [1 | rest]
[1, 2, 3]
iex(3)> ^list = [1,2,3,4]
** (MatchError) no match of right hand side value: [1, 2, 3, 4]
iex(3)> [1 | rest] = [1,2,3,4]
[1, 2, 3, 4]
``````

The same thing happens with maps as you observe. When you do `^foo =` itâ€™s going to check that `foo` is exactly equal to the relevant part of the right hand side, it isnâ€™t going to convert `foo`'s value into a pattern.

5 Likes

OK, I understand, thank you.

I thought I could use `^` to â€śreuseâ€ť a pattern like this:

``````^pattern = value
^pattern = other_value
...
``````