この場合、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: "[email protected]", name: "Deedub"}}
else
{:error, "Age isn't in the right range"}
end
end
end
可能なリターンブランチの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: "[email protected]", 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>>}}
私が理解していない部分は、ダイアライザーがブランチが返す可能性のある2つの異なるタイプを明確に認識することです((#{'id':=_, _=>_},_) -> 10 | {'ok',#{'email':=<<_:64>>, 'name':=<<_:48>>}
)。したがって、推論の問題ではありません。では、なぜブランチの1つがタイプ仕様に準拠していないことを認識しないのですか(ブランチの1つだけが準拠していれば幸いですが、これは私が望んでいることではありません)
Dogbertが提供したLearnYouリンクから、次のdialyzer
ようになります。
クラッシュを保証するタイプエラーについてのみ文句を言います。
最初の例では、年齢が常に100以上の場合、関数は宣言された型を返します。2番目の例では、関数が宣言された型を返す方法はありません。
dialyzer
一連の制約方程式を作成します。これらの方程式に解決策があれば、ダイアライザーは文句を言いません。Erlangは動的に型付けされた言語として作成されました。dialyzer
事後に誰かが書いたプログラムにすぎません。彼らが熟考し、議論し、理論化したと確信している理由から、ダイアライザーの設計者はその機能を選択しました。
可能であれば、より厳密な型チェッカーを探しています。
今のところ不可能:
Erlang型システム
より精巧な型システムを持たない理由は、Erlangの発明者の誰もがそれを書く方法を知らなかったので、それが成し遂げられなかったからです。静的型システムの利点は、エラーを実行時ではなくコンパイル時に予測できるため、障害を早期に検出して低コストで修正できることです。多くの人がErlang用の静的型システムを構築しようとしました。残念ながら、Erlangが発明されたときに行われた設計上の決定により、ホットコードのロードでは本質的に困難であるため、包括的な型システムを作成できるプロジェクトはありませんでした。多くの型システムの炎上戦争の1つでJoeArmstrongを引用すると、「それは「簡単」であるはずです。実際、数週間のプログラミングで、言語の95%を処理する型システムを作成できます。
「ErlangProgramming(Francesco Cesarini&SimonThompson)」より。
test suite
動的に型指定されたプログラムを制御下に置くには、Aが必要です。ElixirはErlangの単なるRubifiedバージョンです。Rubyも動的に型付けされた言語ですが、ダイアライザーはありません。Rubyが持っているのはテストだけです。テストスイートを使用して、コンパイラではなく、コンピュータプログラミング言語のワイルドウェストを管理下に置きます。静的に型付けされた言語が必要な場合は、RubifiedバージョンのErlangは最適ではありませんでした。Haskellを参照してください。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加