2013-03-23 11 views
10

Ich habe ich eine Funktion mit zwei Argumente, die ich Muster übertreffen muss. Wenn ich currying auf dem ersten Muster verwenden, wird es nicht kompilieren:Warum kann ich eines der Muster curry aber nicht das andere in meinem Muster übereinstimmen?

drop' :: Int -> [a] -> [a] 
    drop' 0 = id -- ghci: "Equations for drop' have different numbers of arguments" 
    drop' n (x:xs) = drop' (n-1) xs 

Der Compiler diesen Ausgang gibt:

99.hs:106:3: 
Equations for drop' have different numbers of arguments 
    99.hs:106:3-15 
    99.hs:107:3-33 
In an equation for `split': 
    split xs n 
     = (take' n xs, drop' n xs) 
     where 
      take' 0 _ = [] 
      take' n (x : xs) = x : take (n - 1) xs 
      drop' 0 = id 
      drop' n (x : xs) = drop' (n - 1) xs 
Failed, modules loaded: none. 

Wenn ich nur das curried Muster geben, aber dann kompiliert es:

drop' :: Int -> [a] -> [a] 
    drop' 0 = id -- compiles 

Was gibt?

+1

Angenommen, Sie können einfach 'drop' 0 x = x 'schreiben? – Koterpillar

+3

Alle Gleichungen, die eine Funktion definieren, müssen die gleiche Anzahl von Argumenten haben. Also 'drop 0 = id; drop n = \ (_: xs) -> drop (n-1) xs' würde kompilieren. –

+4

[Beachten Sie, dass alle Klauseln, die eine Funktion definieren, zusammenhängend sein müssen, ** und die Anzahl der Muster in jeder Klausel muss gleich sein. **] (http://www.haskell.org/onlinereport/haskell2010/haskellch4.html# x10-830004.4.3) –

Antwort

10

Die einzige Erklärung, die ich (http://www.haskell.org/pipermail/haskell-cafe/2009-March/058456.html) finden konnte:

Das Problem ist vor allem syntaktisches, in dem Sinne, dass die meisten Vorkommen von Definitionen mit einer unterschiedlichen Anzahl von Argumenten sind einfache Tippfehler. Die andere könnte Umsetzungsprobleme sein: Es macht Muster Match-Regeln komplexer.

+0

Es scheint mir, dass in den verschiedenen Haskell-Berichten viel darüber nachgedacht wurde, wie man sich vor Programmierfehlern schützen kann, ohne das zu opfern, was man in der Sprache ausdrücken kann. Siehe auch Daniel Fischers Kommentar, und sogar die gefürchtete Monomorphismus-Beschränkung fällt in diese Kategorie. Es ist ein kleiner Streit, aber du wirst es später dafür dankbar sein. – yatima2975

+0

@ yatima2975 Ich kann verstehen, dass die gängigen Programmierer Fehler im Keim ersticken wollen. Aber könnte es nicht nur eine Compilerwarnung sein? Obwohl ich denke, dass eine Reihe von Compiler-Warnungen nervig sein könnte (ganz zu schweigen von den möglichen Annotationen, um sie zu unterdrücken), ist das ein guter Kompromiss, da ich mir keinen Fall vorstellen kann, in dem der Code wesentlich weniger aussagekräftig wäre diese leichte Einschränkung. – Guildenstern

1

Ich kann Ihnen nicht warum sicher sagen, aber das ist eine bekannte Einschränkung. Alle Fälle derselben Funktion müssen die gleiche Anzahl von Argumenten haben.

1

Dies ist ein ärgerliches „Feature“ von GHC, um sicher zu sein, aber es zu beheben, können Sie dies tun:

drop' n = \(x:xs) -> drop' (n-1) xs 

Sie haben beide Curry oder keines von beiden, und beide auf die gleiche Anzahl der Argumente. Wenn das eine Flusenprüfung ist, ist das großartig: aber ich wünschte, es gäbe eine Compileroption, um sie ein-/auszuschalten.

+2

Da dies identisch mit der anderen Definition ist (und tatsächlich ausführlicher), besiegt es den Punkt ein wenig IMHO. – jozefg

+0

@jozefg Ich postete das, weil ich die anderen Antworten ohne weitere Untersuchung nicht verstehen konnte: ein alternativer Blickwinkel ist oft nützlich. – jpaugh