2015-07-09 7 views
6

In meinem Fortschritt des Lernens Elixir, spiele ich mit Dialyzer herum, um Typen auf meinen Funktionen zu setzen. In diesem Zusammenhang habe ich bemerkt, dass Dialyzer die Typen anscheinend nicht auf anonyme Funktionen überprüft.Analysiert Dialyzer anonyme Funktionen?

Im folgenden Beispiel übergebe ich eine anonyme Funktion, die zwei Zahlen hinzufügt und eine Zahl (t::number -> number) an die all?-Funktion zurückgibt. Daher gebe ich keinen Booleschen Wert zurück, wie es in der all? Spezifikation (t::any -> boolean) versprochen wurde.

defmodule Exercises do                   
    @spec all?([t::any], (t::any -> boolean)) :: boolean           
    def all?([], _), do: true                 
    def all?([h|t], con) do                  
    if con.(h) do                    
     all?(t,con)                    
    else                      
     false                      
    end                       
    end                       

    @spec funski() :: boolean                  
    def funski() do                    
    all?([1,1,2], &(&1 + 1))                 
    end 
end 

Dialysator scheint keine Fehler oder Warnungen für diesen Code zu melden, und ich bin Kuriosität, wenn Dialysator nicht in der Lage ist, diese Art von Fehlern zu überprüfen oder wenn ich etwas falsch tue.

Antwort

2

Es scheint ein Dialyzer Bug zu sein. Der Aufruf von :lists.all/2 (mit den ausgetauschten Argumenten) erzeugt die richtige Warnung, aber aus irgendeinem Grund ruft das Aufrufen Ihrer lokalen all?/2-Funktion mit der gleichen Spezifikation nicht auf.

+0

tauschen die Argumente von 'alle?/2' macht Dialyzer Ausbeute folgende Warnung' Der Aufruf 'Elixir.Exercises': 'alle?' (Spaß ((_) -> Anzahl()), [1 | 2 ,. ..]) wird nie zurückkommen, da die Erfolgstypisierung (Maybe_improper_list(), any()) -> boolean() ... 'ist. Aber ich sehe nicht, wie das mit der Analyse der anonymen Funktion '& (& 1 + 1) zusammenhängt.' – Michelrandahl

+0

Ich meinte, wenn man ': lists.all/2' aufruft (eine völlig andere Funktion), sollten Sie die Argumente tauschen. Und wenn Sie diese Funktion aufrufen, erhalten Sie die richtige Warnung. Es scheint also ein Fehler im Dialysator zu sein, der die Warnung für Ihre Funktion nicht bekommt. –

+0

ah Entschuldigung, ich vermisse deine Antwort. Aber ': list.all (& (& 1 + 1), [1,1,2])' lässt Dialyzer keine Warnungen ausgeben, wenn ich ihn anstelle des "alle" ([1,1,2] . & (& 1 + 1)) '.. Vielleicht hat es etwas mit dem generierten' .beam'-Code zu tun, der vom Elixir-Compiler erzeugt wird, dem ich Dialyzer füttere ... – Michelrandahl