この場合、Dialyzer はかなり奇妙に動作しますが、それをよりよく理解できるものは何も見つかりませんでした。
これはエラーではありません:
defmodule Blog.UserResolver do
@type one_user :: ( {:error, String.t} )
@spec find(%{id: String.t}, any()) :: one_user
def find(%{id: id}, _info) do
age = :rand.uniform(99)
if (age < 100) do
# This doesn't trigger a type error, even though it's wrong
{:ok, %{email: "dw@1g.io", name: "Deedub"}}
else
{:error, "Age isn't in the right range"}
end
end
end
考えられる return ブランチの 1 つが、型シグネチャと完全に一致しないことに注意してください。
ただし、これにはエラーがあります。
defmodule Blog.UserResolver do
@type one_user :: ( {:error, String.t} )
@spec find(%{id: String.t}, any()) :: one_user
# Throws an error since no return path matches the type spec
def find(%{id: id}, _info) do
age = :rand.uniform(99)
if (age < 100) do
{:ok, %{email: "dw@1g.io", name: "Deedub"}}
else
10
end
end
end
この場合、可能性のあるブランチはどれもtypespec に一致せず、dialyzer は次のエラー メッセージを表示します。
web/blog/user_resolver.ex:4: Invalid type specification for function 'Elixir.Blog.UserResolver':find/2. The success typing is (#{'id':=_, _=>_},_) -> 10 | {'ok',#{'email':=<<_:64>>, 'name':=<<_:48>>}}
私が理解していない部分は、dialyzerがブランチが返す可能性のある 2 つの異なる型 ( ) を明確に(#{'id':=_, _=>_},_) -> 10 | {'ok',#{'email':=<<_:64>>, 'name':=<<_:48>>}
認識しているため、推論の問題ではないということです。では、ブランチの 1 つが型仕様に準拠していないことを認識しないのはなぜですか (ブランチの1 つだけが準拠していれば幸いですが、これは私が望んでいるものではありません)。