所以我想说我有这样的函数:
def something(callback) do
case *some condition* do
0 ->
:ok
1 ->
{:error, :foo}
_ ->
callback.()
end
end
回调函数可以返回:ok
或{:error, *some atom*}
,其中某个原子是未知原子。
现在,我想知道是否有办法为something/1
函数编写不使用常规atom
规范的规范。所以,问题是,基本上,如果有一种方法来编写比这更具体的类型:
@spec something(() -> :ok | {:error, atom}) :: :ok | {:error, atom}
相反,我希望我的规范显示something/1
函数可以返回:ok
,{:error, :foo}
或callback
返回的值
PS我知道这种事情在实际层面上并不重要,所以这只是一个基于好奇心的问题。
答案 0 :(得分:2)
您正在寻找类型变量。 Erlang does support声明他们但透析器目前似乎没有基于这些类型进行任何检查(Erlang / OTP 20)。
可以在规范中使用类型变量来指定函数的输入和输出参数的关系。例如,以下规范定义了多态标识函数的类型:
-spec id(X) -> X.
您想要的类型签名是:
@spec something(() -> t) :: :ok | {:error, atom()} | t
答案 1 :(得分:1)
您可以为@type
的返回类型定义callback/0
,例如@type callback_return_type :: atom
然后使用:@spec something(fun()) :: :ok | :error | callback_return_type
PS我知道这种事情在实际上并不重要 等级,所以这只是一个基于好奇心的问题。
在大型项目中,Typespec可组合性很重要,以确保一致性并避免代码重复。您在module
中声明的类型可由其他modules
重复使用,您甚至可以将某些typespecs
声明为private
和opaque
,从而为您提供精细的细节控制它们的使用方式,以便您可以保持图书馆用户关注点的分离。