- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
free_vars_in_dterm({var, V}) -> {var, V};
显然不能类型检查,然而,dialyzer 说一切正常。
$ dialyzer *erl
Checking whether the PLT ~/.dialyzer_plt is up-to-date... yes
Proceeding with analysis... done in 0m0.66s
done (passed successfully)
代码如下:
-module(formulas).
-type formulas() :: {predicate(), [dterm()]}
| {'~', formulas()}
| {'&', formulas(), formulas()}
| {'|', formulas(), formulas()}
| {'->', formulas(), formulas()}
| {'<->', formulas(), formulas()}
| {'exist', variable(), formulas()}
| {'any', variable(), formulas()}.
-type dterm() :: constant()
| variable()
| {func(), [dterm()]}.
-type constant() :: {const, atom()}
| {const, integer()}.
-type variable() :: {var, atom()}.
-type func() :: {function,
Function_name::atom(),
Arity::integer()}.
-type predicate() :: {predicate,
Predicate_name::atom(),
Arity::integer()}.
-include_lib("eunit/include/eunit.hrl").
-export([is_ground/1, free_vars/1, is_sentence/1]).
-spec is_ground(formulas()) -> boolean().
is_ground({_, {var, _}, _}) -> false;
is_ground({{predicate, _, _}, Terms}) ->
lists:all(fun is_ground_term/1, Terms);
is_ground(Formulas) ->
Ts = tuple_size(Formulas),
lists:all(fun is_ground/1, [element(I, Formulas)
|| I <- lists:seq(2, Ts)]).
-spec is_ground_term(dterm()) -> boolean().
is_ground_term({const, _}) -> true;
is_ground_term({var, _}) -> false;
is_ground_term({{function, _, _}, Terms}) ->
lists:all(fun is_ground_term/1, Terms).
-spec is_sentence(formulas()) -> boolean().
is_sentence(Formulas) ->
sets:size(free_vars(Formulas)) =:= 0.
-spec free_vars(formulas()) -> sets:set(variable()).
free_vars({{predicate, _, _}, Dterms}) ->
join_sets([free_vars_in_dterm(Dterm)
|| Dterm <- Dterms]);
free_vars({_Qualify, {var, V}, Formulas}) ->
sets:del_element({var, V}, free_vars(Formulas));
free_vars(Compound_formulas) ->
Tp_size = tuple_size(Compound_formulas),
join_sets([free_vars(element(I, Compound_formulas))
|| I <- lists:seq(2, Tp_size)]).
-spec free_vars_in_dterm(dterm()) -> sets:set(variable()).
free_vars_in_dterm({const, _}) -> sets:new();
free_vars_in_dterm({var, V}) -> {var, V};
free_vars_in_dterm({{function, _, _}, Dterms}) ->
join_sets([free_vars_in_dterm(Dterm)
|| Dterm <- Dterms]).
-spec join_sets([sets:set(T)]) -> sets:set(T).
join_sets(Set_list) ->
lists:foldl(fun (T, Acc) -> sets:union(T, Acc) end,
sets:new(),
Set_list).
最佳答案
首先是一个简短的回答,使用 Dialyzer 的格言:
最大数字 2 是(诚然不是很令人满意)对任何“为什么 Dialyzer 没有捕获到这个错误”问题的“标准”答案。
更具解释性的答案:
Dialyzer 对函数返回值的分析经常会过度逼近。因此,类型中包含的任何值都应被视为“可能返回”的值。这有一个不幸的副作用,有时肯定会返回的值(例如您的 {var, V}
元组)也被视为“可能返回”。 Dialyzer 必须保证 maxim 1(永远不会出错),因此在“可能返回”意外值的情况下,它不会发出警告,除非无法返回任何实际指定的值。最后一部分在整个函数级别进行检查,并且由于在您的示例中某些子句确实返回集合,因此不会生成任何警告。
关于types - 为什么 Erlang Dialyzer 在以下代码中找不到类型错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43070330/
在我学习 Elixir 的过程中,我正在使用 Dialyzer 来为我的函数添加类型。在这方面,我注意到 Dialyzer 似乎没有检查匿名函数的类型。 在下面的示例中,我传递了一个匿名函数,该函数将
-module(test). -export([f/0, g/0]). -spec f() -> RESULT when RESULT :: 0..12 . -spec g() -> RE
我正在饶有兴趣地阅读在线书籍“learn you some erlang”并尝试一些练习来检查我的理解。 我在 一章中对 fifo 示例做了一些修改。类型规范和 Erlang ,试图定义一个“type
我希望添加规范永远不会降低安全性,但这正是以下情况发生的情况。 在下面的代码中, Dialyzer (错误地)相信我 bar 的返回类型是 1 。这导致它说 foo() 中的模式永远不能匹配 - 如果
我正在使用 elixir_talk 库。连接后,我想在连接到 beanstalkd 后调用一个私有(private)函数。我刚刚添加了 typespecs 并运行了 Dialyzer(通过 dialy
我正在使用带有一些自定义行为的 Dialyzer,问题是当我这样做时,Dialyzer 会给我这个错误: src/max.erl:3: Callback info about the gen_stra
我根据 this 创建了下面的代码片段教程。最后两行(feed_squid(FeederRP) 和 feed_red_panda(FeederSquid))显然违反了定义的约束,但 Dialyze
我正在使用 构建 PLT dialyzer --output_plt lib.plt --build_plt --apps stdlib kernel mnesia ssl public_key c
Dialyzer 不会发出此函数返回类型不一致的信号: -spec myfun(integer()) -> zero | one. myfun(0) -> zero; myfun(1) -> one;
现在,我尝试使用 Dialyzer 并使用 -spec,-type。 我将以下代码提供给 Dialyzer,我希望 Dialyzer 注意到“hoge(a) + 1 无效”,但 Dialyzer 没有
您能否将 Dialyzer PLT 输出复制并使用到另一台不同架构的机器上?例如,我在 x86_64 Linux 机器上构建了一个 PLT 文件。我可以在 x86 FreeBSD 或 Windows
free_vars_in_dterm({var, V}) -> {var, V}; 显然不能类型检查,然而,dialyzer 说一切正常。 $ dialyzer *erl Checking whe
当 Dialyzer 遇到未初始化所需字段的记录文字时,它认为控制流在记录文字所在的行处停止。 例子: -module(sample). -export([foo/0]). -record(boo,
我在 ~/erl_beam 之类的路径下收集项目的所有梁文件 dialyzer ~/erl_beam/*.beam --get_warnings -o static_analysis.log 它运作良
我定义了 Elixir 行为 X。回调 start_link 指定为: @callback start_link( args :: producer_args, opts :: GenServ
当独立运行 Dialyzer 时,它使用 HiPE 编译其模块,以加快分析速度: dialyzer --src -r . Checking whether the PLT /home/foo/.d
我想要 Erlang 中等效的 Java 接口(interface)。如何为透析器提供 -spec 合约,使我能够尽可能接近 Java 中提供的功能? 假设我想要与此等效的东西: //Filename
我在我的电脑上使用 asdf 安装了 elixir 1.7.2,包括 elixir 和 erlang otp 21。在我的项目混合文件中,我按照 dialyzer github 上的说明添加了透析器的
我有以下代码: @spec test_pass(String.t) :: (:failed | {:ok, map()}) def test_pass(pass) do db_user = %{p
我正在使用 Dialyzer 修复 Erlang 代码中的错误。 io:format(IoDevice, "[]"); 此行产生以下错误: The call io:format(IoDevice::p
我是一名优秀的程序员,十分优秀!