2016-03-05 28 views
1

有沒有辦法讓功能「類型」在Elixir中實現協議?我正在玩一個自定義的Functor協議,並想知道我是否可以使功能實現它(忽略Elixir類型系統的所有限制)。「功能」可以在Elixir中實現協議嗎?

實現(如果function其中A型)將

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 

不,我想用這個事情的嚴重性,只是想知道。

+0

以下是Elixir中的類別庫https://github.com/robot-overlord/witchcraft這可能有助於瞭解他們已經完成的工作。 – CoderDennis

回答

0

由於Erlang/Elixir是動態輸入的,嚴格的答案是否定的。函數實際上僅由arity(或者對於命名函數,模塊,函數名稱和元數據)來區分。

您可以通過Typespecs指定更多特定類型,透析器(可通過dialyxer在混合任務中使用)將對此做一些斷言,但這不是編譯工具鏈或運行庫的一部分,並且不提供任何保證。並非所有的違規行爲都會被透析器捕獲(這是基於成功打字),但這是一個好的開始。

+0

我真的不需要關於其arity的保證。查看更新。 –

+0

雖然我不知道答案會有什麼變化。如果你不能用類型描述來表達,你可能一無所有。如果你可以通過類型描述來表達它,你可以用宏做技巧來幫助你自己。 – asonge

0

我不確定你爲什麼需要這個Protocol ...抱歉,如果我錯過了一些重要的問題。您可以實現與警衛功能,做這雖然:

defmodule Functor do 
    def fmap(f, g) where is_function(f) and is_function(g) do 
    &(g.(f.(&1))) 
    end 
end 

,然後你可以這樣寫:

iex> f_2x_plus_1 = Functor.fmap(&(&1 * 2), &(&1 + 1)) 
#Function<0.100612233/1 in Functor.fmap/2> 
...> f_2x_plus_1.(1) 
3 

我想我只是不知道該協議得到你的函數沒有按」噸。

+1

在Haskell中,Functor是一個類類,而不是具體的類型。 Elixir中最好的模擬器(以及它的工作非常好)是一個協議。所以我一直在移植一些(類別理論)類型類,如Functor,Applicative,Monad,Monoid,SemiGroup等。一個協議讓我通過一個函數是基於類型的調度和可擴展性。這個想法是,你創建一個處理Monoid的庫,你爲你的自定義結構/類型實現了Monoid Protocol,你可以將它傳遞給那個模塊。 –

1

事實證明,你可以。這是我的工作什麼可能導致庫中的實現,叫做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 

這是對入門

http://elixir-lang.org/getting-started/protocols.html

+0

那麼這是什麼讓你?我仍然不清楚您嘗試啓用的語法。 –

+0

@ChrisMeyer在Haskell(和Cathegory Theory)中的一個函數是Functor(也是一個Applicative和Monad)。有用或不是我想要使用協議在Elixir中實現常見的Haskell類型類。我猜Monads不會是那種流行的en elixir,但是monoid可以是非常有用的。 –

1

您的例子並不構成一個整體的協議部分因爲在elixir中只有單一類型的功能,所以對我來說很有意義,但功能是可以實現協議的類型。

defimpl Category.Functor, for: Function do 
    def fmap(f, g), do: &(g.(f.(&1)) 
end 

,我看到的問題是,元數是仙丹/二郎非常重要的,我不知道如何以簡單的方式解釋這一點。

+0

看到我自己的答案。它不是理想的手工檢查,但我想它是唯一的方法。 –

+0

有時可以使用Kernel.apply來解決元組問題。 –

+0

嗯...但我不認爲我實際上可以使用'apply',因爲它的功能組成,你實際上不能評估。 –