Erlang 透析器能看穿Mnesia交易功能吗?

Erlang 透析器能看穿Mnesia交易功能吗?,erlang,mnesia,dialyzer,Erlang,Mnesia,Dialyzer,下面是一些代码,其中有一个错误,我认为透析器应该能够发现: -module(myapp_thing). -spec exists(pos_integer()) -> yes | no. exists(Id) -> myapp_mnesia:thing_exists(Id). myapp_thing:exists/1指定为返回yes | no,但返回类型实际上是true | false(即boolean()),这是从myapp_mnesia:thing_exists/1

下面是一些代码,其中有一个错误,我认为透析器应该能够发现:

-module(myapp_thing).

-spec exists(pos_integer()) -> yes | no.
exists(Id) ->
    myapp_mnesia:thing_exists(Id).

myapp_thing:exists/1
指定为返回
yes | no
,但返回类型实际上是
true | false
(即
boolean()
),这是从
myapp_mnesia:thing_exists/1
返回的内容

然而,在myapp上运行透析器时,没有发出警告

如果我更改
myapp\u mnesia:thing\u exists/1
以仅返回
true
,我将得到相应的警告;同样,如果我添加了正确的规范:

-spec session_exists(pos_integer()) -> boolean().
但看起来透析器无法查看mnesia事务函数的内部存在,或者由于其他原因无法推断出存在的东西的返回类型


那么,mnesia transaction函数是透析器的障碍,还是透析器的返回类型推断存在更普遍的障碍?

mnesia_tm:execute_transaction
中,提供的乐趣在
catch
中调用,这意味着返回类型折叠为
术语()
关于透析器。因此,透析器无法断定
mnesia:activity/2
的返回类型与提供的函数的返回类型相同,因此需要明确的类型规范

此外,我相信透析器通常不会根据作为参数提供的函数的返回值推断返回值类型。例如,使用此模块:

-module(foo).

-export([foo/1]).

foo(F) ->
    F(42).
typer显示以下内容:

$ typer /tmp/foo.erl

%% File: "/tmp/foo.erl"
%% --------------------
-spec foo(fun((_) -> any())) -> any().
虽然如果我添加显式类型spec
-spec foo(fun(()->X))->X.
,那么typer会接受它


(我相信透析器开发人员对此会有一个更完整、更深刻的答案。)

据我所知,
mnesia:activity/2
没有类型
-spec
。添加类似于
-spec mnesia:activity(atom(),fun(()->X))->X的内容。
可能会有所帮助(尽管我没有尝试过)。您可以在函数规范中使用类型变量!?酷!然而,我不想摆弄记忆的来源。我正在myapp_mnesia中键入函数。我想知道更多关于透析器推理的障碍。
$ typer /tmp/foo.erl

%% File: "/tmp/foo.erl"
%% --------------------
-spec foo(fun((_) -> any())) -> any().