Nein, können Sie nicht. Das grundlegende Problem ist, dass Haskells Syntax Sie dazu verleitet hat zu denken, dass die Typen f1
und f2
ähnlicher sind, als sie wirklich sind. Einmal übersetzt in GHC Kern, sie sehen eher anders aus:
f1 :: forall a . a -> [a]
f2 :: Int -> Int
Nicht nur das, sondern die entsprechenden Begriffe Blick etwas anders:
f1 = Λa -> λ(x :: a) -> [x]
f2 = λ(x :: Int) -> 3 * x
Wie Sie sehen können, f1
und f2
tatsächlich haben verschiedene Anzahlen von Argumenten, wobei f1
einen Typ und einen Wert unddauertbraucht nur einen Wert.
In gewöhnlicheren Umständen, wenn Sie f2
in einen Kontext eine Funktion vom Typ plop erwarten, sagen wir, Int -> [Int]
, GHC f2
auf die notwendige Art gelten für Sie (dh f2
auf einen bestimmten Typ instanziiert), und alle werden gut sein. Zum Beispiel, wenn Sie
g :: (Int -> [Int]) -> Bool
haben, und Sie gelten g
-f
wird GHC kompilieren eigentlich, dass zu
g (f @Int)
Aber hier wollen Sie Polymorphismus darüber, ob das Instanziierung geschieht oder nicht, die GHC doesn‘ t Unterstützung (ich denke, es wäre eine ziemlich radikale und destruktive Änderung der Kernsprache).
Da Klasseninstanzen, Familienmuster und Typ Familienergebnisse nicht quantifizierbar sind, bin ich ziemlich zuversichtlich, dass es überhaupt keine Möglichkeit gibt zu bekommen, was Sie wollen.
als @ErikR zeigte Ihnen in seiner (jetzt gelöscht) Antwort die linke Seite ist machbar, aber der Typ auf der rhs hängt von der Art von 'f' so denke ich, dass Sie Typfamilien auch verwenden müssten - wenn das für Sie in Ordnung ist, dann sollte das natürlich nur eine Vermutung sein - denn alles, was ich weiß, gibt es eine Möglichkeit, dies auszudrücken;) – Carsten
Gerne GHC-Erweiterungen verwenden – Clinton
@ user3237465: auf einen Blick (zumindest deine einfache Version) Ich denke, du würdest mit 'f2' in Schwierigkeiten kommen, weil das nicht * forall a * ist, sondern nur für' Int' mehr – Carsten