2017-05-31 4 views
2

Ich versuche, den Punkt freie Form von f x y = 3 + y/x in Haskell herauszufinden. Ich dachte, es wäre f = (3.0+) . flip (/), aber die Antwort ist f2 = curry $ (3.0+) . (uncurry $ flip (/)), das ist das gleiche wie f1 = curry ((3.0+) . (uncurry (flip (/)))), z.B. die antwort bekam ich aber mit uncurry vorher flip und curry am anfang.f x y = 3 + y/x in Punkt freie Form

Ich sehe, wie diese Version funktioniert, aber ich bin mir nicht sicher, warum die Curry und Uncurry-Funktionen benötigt werden, und warum meine Version nicht funktioniert? Die Art von (3.0+) ist a -> a, die ich dachte, würde funktionieren, wenn Sie diese Funktion mit dem Ergebnisformular flip (/) über Funktionszusammensetzung gefüttert, aber (3.0+) . flip (/) 2 10 führt zu einem Fehler (warum?) Und ergibt nicht 8. Ist es nicht redundant zu uncurry und dann wieder curry?

+0

https : //hackage.haskell.org/package/pointfree – Hapal

Antwort

4

Die Typensignatur des . ist (.) :: (b -> c) -> (a -> b) -> a -> c. Wie Sie sehen können, funktioniert dies nur, wenn die Sekunde Funktion (in Ihrer Antwort flip (/)) ein Argument hat. Falls es zwei Argumente hat, können wir die „Eule Operator“ (.) . (.) verwenden, die Art hat:

(.) . (.) :: (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c 

Oder wir currying nutzen können. Durch die Verwendung von uncurry :: (a -> b -> c) -> (a, b) -> c auf dem flip (/) Teil konstruieren wir eine Funktion:

uncurry (flip (/)) :: Fractional c => (c, c) -> c 

so jetzt arbeiten wir mit einem einzigen Tupel (also ein Argument), und dann verwenden wir curry :: ((a, b) -> c) -> a -> b -> c, um das resultierende erste Argumenttupel „entpacken“ nochmal.

Alternativen

Wie bereits erwähnt, können wir die Eule Operator:

((.) . (.)) (3.0+) (flip (/)) 
--^ owl ^

Oder können wir eine syntaktisch komplexere Version der Eule Operator verwenden:

((3 +) .) . flip (/) 
Verwandte Themen