2

この場合、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 つだけが準拠していれば幸いですが、これは私が望んでいるものではありません)。

4

1 に答える 1