Kürzeste a -> b -> (a -> b) -Funktion in Haskell


19

Bei einem Test habe ich folgende Frage bekommen:

Schreiben Sie eine Funktion fmit folgendem Typ a -> b -> (a -> b). aund bsollte in keiner Weise gebunden sein, je kürzer der Code, desto besser.

Ich habe es mir ausgedacht f a b = \x -> snd ([a,x],b). Kannst du etwas winzigeres finden?

Derzeit ist der Gewinner: f _=(.f).const


Wenn ein allgemeinerer Art ist erlaubt: f = const const.
Hammar

@ Hammar: oder f _ b _ = b, aber angesichts der Lösung in der Frage, ich vermute, ein allgemeinerer Typ ist nicht zulässig.
Tikhon Jelvis

6
Wenn ein allgemeinerer Typ zulässig ist, warum nicht f = id?
Tom Ellis

7
In der Tat, wenn ein allgemeinerer Typ erlaubt ist, dann f = fist eine Lösung, also denke ich, dass die Bedingungen für den Typ sehr wichtig sind!
Tom Ellis

2
Ein allgemeinerer Typ ist nicht zulässig, da Ihre Annahmen korrekt waren.
Radu Stoenescu

Antworten:


11

Ihr Beispiel kann verkleinert werden, indem Sie die anonyme Funktion auf der rechten Seite entfernen:

f a b x = snd ([a,x],b)

Dies funktioniert, weil der Typ a -> b -> a -> bdem a -> b -> (a -> b)in Haskell entspricht.


4
Etwas kürzere Änderung:f a b x = snd (f x,b)
Ed'ka

5

Die Funktion f _=(.f).constist eigentlich allgemeiner als f :: a -> b -> (a -> b), nämlich f :: a -> b -> (c -> b). Wenn keine Typensignatur angegeben ist, leitet das Typinferenzsystem einen Typ von ab f :: a -> b -> (a -> b). Wenn Sie jedoch die Typensignatur f :: a -> b -> (c -> b)mit genau derselben Definition einfügen, kompiliert Haskell sie ohne Probleme und gibt konsistente Typen für die Teilanwendungen von f aus. Es gibt wahrscheinlich einen tiefen Grund, warum das Typinferenzsystem in diesem Fall strenger ist als das Typprüfsystem, aber ich verstehe nicht genug Kategorietheorie, um einen Grund dafür zu finden, warum dies der Fall sein sollte. Wenn Sie nicht überzeugt sind, können Sie es gerne selbst versuchen.


könnte wie der Fall sein f a b = f a a. es folgt daraus, dass es vom Typ ist, a -> a -> bobwohl es dem Typ entspricht a -> b -> c. es liegt daran, dass fes sich nur monomorph verwenden kann, wenn es keinen Typ erhält.
stolzer Haskeller

Ich denke nicht, dass das eine Rolle spielen sollte
stolzer Haskeller

4

In Anbetracht ScopedTypeVariables, kam ich mit auf den Punkt :

f (_::a) b (_::a) = b

Wenn Sie sowohl meine als auch Ihre Funktion einschränken, ist meine Haarlänge kürzer:

f(_::a)b(_::a)=b
f a b x=snd([a,x],b)

Natürlich dürfen Sie sich wahrscheinlich nicht auf Folgendes verlassen ScopedTypeVariables: P.


3
Dies ist nicht so kurz wie f _=(.f).const ( aufgrund von Sassa NF ). Welches braucht auch nicht ScopedTypeVariables.
aufgehört, sich

Hmm, ich dachte zunächst, dass das erste und dritte Argument Listen sein müssten ...
Chris Taylor,

@ ChrisTaylor: Zu viel OCaml im Kopf? :)
Tikhon Jelvis

Hah, muss sein! ;)
Chris Taylor
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.