首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么Dialyzer告诉我这个有趣的合同有重叠的领域?

为什么Dialyzer告诉我这个有趣的合同有重叠的领域?
EN

Stack Overflow用户
提问于 2012-08-30 12:54:52
回答 2查看 936关注 0票数 8

我正在感兴趣地阅读在线书"给你学点二郎“,并尝试一些练习来检查我的理解。

类型规范和Erlang一章中,我对fifo示例做了一些修改,试图定义一个"typed_fifo( T)“(一个fifo,其中所有元素都必须是相同类型的T)。

我的类型说明是:

-type typed_empty_fifo() ::{fifo,[],[]} -type typed_nonempty_fifo(A):{fifo,nonempty_list(A),list(A)} {fifo,[],nonempty_list(A) } -type typed_fifo(A) ::typed_empty_fifo() x typed_nonempty_fifo(A)。

当我在以下函数规范中使用它时:

-spec空(typed_empty_fifo()) -> true; (typed_nonempty_fifo(_)) -> false. 空({fifo,[],[]}) ->真; 空({fifo,A,B})当is_list(A),is_list(B) ->假。

Dialyzer说,它将忽略规格,因为重叠的领域。

有人能告诉我哪里出错了吗?

我还有一个观点,在尝试定义输入fifo之前,我有一个运行良好的版本,一个透析器告诉我,没有什么能阻止使用不正确的列表。显然,我没有找到一种简单的方法(我可以在警卫中使用)来测试列表的适当/不适当的性质。

这真的很奇怪,因为当我使用bif长度/1时,它就会失败,原因是badarg!

水飞虱( 23> L=1,2|3. ==> )1,2~3 24> is_list(L.)==>真 25>长度(L)。==>异常错误:错误参数 在函数长度/1中称为长度(1,2/3)

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-08-30 19:24:02

你的类型和规格没有什么问题。问题是,在透析器中用于表示类型的数据类型并不像您所提供的那样精确。具体来说,联合:{fifo, nonempty_list(A), list(A)} | {fifo, [], nonempty_list(A)}被“压碎”成{fifo, list(A), list(A)},因为元组具有相同的一致性(3)和第一个原子元素(fifo)。透析器通常做过近似(你也可以看到这里),以使类型分析更有效。您可以安全地忽略此警告。

对于第二个问题,is_list/1只检查作为其参数传递的术语的第一个构造函数是否为反单元格。甚至is_list([1|2])也返回true

如果要确保参数是正确的列表,可以在case表达式中使用以下自定义函数:

代码语言:javascript
运行
复制
case is_proper_list(L) of
  true -> ...;
  false -> ...
end

is_proper_list([]) -> true;
is_proper_list([_|L]) -> is_proper_list(L);
is_proper_list(_) -> false.

不过,这不能放在警卫身上。在警卫中,您可以使用您在下面的评论(length(L) >= 0)中建议的。

票数 6
EN

Stack Overflow用户

发布于 2012-08-30 13:49:23

关于您的第二个问题,使用list的正确方法是:

代码语言:javascript
运行
复制
1> L = [1,2|[3]].
[1,2,3]
2> is_list(L).
true
3> length(L).
3

注意,[Head|Tail]表示法要求Tail必须是list (而不是int)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12197338

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档