有没有办法让函数"type“在Elixir中实现一个协议?我正在尝试一个自定义的Functor
协议,我想知道是否可以让函数实现它(忽略Elixir的类型系统的所有限制)。
实现(如果是function
,其中是类型)将是
defimpl Category.Functor, for: function do
def fmap(f, g), do: &(g.(f.(x))
end
假设你可以这样做
f_2x_plus_1 = &(&1 * 2) |> Functor.fmap(&(&1 + 1))
f_2x_plus_1.(1) == 3
并不是说我会把它用在任何严肃的事情上,只是好奇而已。
发布于 2016-03-07 19:24:13
事实证明你能做到。下面是我正在进行的实现,它可能会产生一个名为excategory
的库
defmodule Category.Function do
def compose(f, g) do
arity_f = :erlang.fun_info(f)[:arity]
arity_g = :erlang.fun_info(g)[:arity]
case {arity_f, arity_g} do
{1, 1} ->
&(g.(f.(&1)))
arities ->
raise "Function are not of arity 1, got #{arities}"
end
end
end
defimpl Category.Functor.P, for: Function do
defdelegate map(f, g), to: Category.Function, as: :compose
end
它位于Getting Started的协议部分
发布于 2016-03-07 19:24:48
你的例子对我来说意义不大,因为在elixir中只有一种类型的函数,但是函数是一种你可以实现协议的类型。
defimpl Category.Functor, for: Function do
def fmap(f, g), do: &(g.(f.(&1))
end
我看到的问题是,在Elixir/Erlang中,数量是非常重要的,我不知道如何以直接的方式说明这一点。
发布于 2016-03-05 20:22:04
因为Erlang/Elixir是动态类型的,所以严格的答案是否定的。函数实际上只通过数量来区分(或者对于命名的函数、模块、函数名称和数量)。
您可以通过Typespecs指定更具体的类型,dialyzer (通过dialyxer在混合任务中可用)将对此进行一些断言,但这不是编译工具链或运行时的一部分,也不提供任何保证。并不是所有的违规行为都会被dialyzer捕捉到(它基于成功的输入),但这是一个很好的开始。
https://stackoverflow.com/questions/35819319
复制