2013-06-02 6 views
13

Ich habe mich gefragt, ob es möglich ist, funktionale Zusammensetzung mit Funktionen zu machen, die mehr als ein Argument benötigen. Ich möchte in der Lage sein, so etwas zu tunFunktionelle Zusammensetzung mit mehrwertigen Funktionen in Haskell?

Einstellung x gleich einer Funktion, die drei zum Produkt von zwei Zahlen addiert.

+4

http://conal.net/blog/posts/semantic-editor-combinators – luqui

+1

[This] (http://stackoverflow.com/questions/9656797/variadic-compose-function) könnte das sein, was Sie suchen . – is7s

Antwort

23

Es gibt mehrere Möglichkeiten, es zu tun, aber sie sind alle etwas peinlich.

((+3).) . (*) 
≡ fmap (+3) . (*) 
≡ curry $ (+3) . uncurry (*) 
≡ \l r -> l*r + 3 

Oh, warten Sie, das war die Unterschrift, wo es auch eine kompakte Definition, erraten, was es ...

((.).(.)) (+3) (*) 

genannt argumentieren, ich würde, dass die Lambda-Lösung, am deutlichsten zu sein, ist eher das Beste hier.

Was hilft und wird oft nur lokal als ein (oder zwei) -Liner getan, ist diese Zusammensetzung als benutzerdefinierte Infix zu definieren:

(.:) :: (c->d) -> (a->b->c) -> a->b->d 
f .: i = \l r -> f $ i l r 

die Sie einfach (+3) .: (*) zu schreiben.

BTW, für die ähnliche (b->b->c) -> (a->b) -> a->a->c (die richtige Funktion zu beide Argumente der Infix precompose) gibt es a widely-used standard implementation.

+1

Ich mag '((.). (.))' Das Beste, vor allem, weil ich mir vorstellen [Frankie Howerd] (http://en.m.wikipedia.org/wiki/Frankie_Howerd) es –

+0

+1 für fmap (das coolste) und das Lambda (das würde ich in jeder Codebase haben wollen, an der ich gerade arbeitete!) – monk

+0

ja - nimm das Lambda oder besser gib der Funktion einen Namen - ganz ehrlich: die anderen Lösungen sind intellektuell erfreulich aber mehr oder weniger unlesbar (Sie können sie leicht wiederfinden, wahr, aber ich würde sagen, unlesbar) - Dinge wie diese gibt Haskell es ist "Arcane Ebenholz-Turm" -Label, die so viele gute Entwickler entmutigt, in Haskell zu suchen – Carsten

2

Sie auch die B1 oder Amsel combinator von Data.Aviary.Birds nutzen könnten. Ich denke für echte Arbeit würde ich ein Lambda verwenden.