Wie kann ich bei Verwendung von GHCi explizite Typdeklarationen für Funktionen bereitstellen?

82

Wie definiere ich das Äquivalent dieser Funktion (aus learnyouahaskell ) in GHCi?

import Data.List  

numUniques :: (Eq a) => [a] -> Int  
numUniques = length . nub  

Ohne die Typdeklaration akzeptiert GHCi die Funktionsdefinition, erhält jedoch einen nicht hilfreichen Typ:

Prelude Data.List> import Data.List 
Prelude Data.List> let numUniques' = length . nub
Prelude Data.List> :t numUniques'
numUniques' :: [()] -> Int

Die resultierende Funktion akzeptiert nur eine Liste von Einheiten als Parameter.

Gibt es eine Möglichkeit, Typdeklarationen in GHCi bereitzustellen? Oder gibt es eine andere Möglichkeit, solche Funktionen zu definieren, für die keine Typdeklarationen erforderlich sind?

Ich sah keine offensichtlichen Hinweise im GHCi-Handbuch und experimentierte mit Ausdrücken wie den folgenden (ohne Erfolg):

> let numUniques' = ((length . nub) :: (Eq a) => [a] -> Int)
> :t numUniques'
numUniques' :: [()] -> Int
mattbh
quelle

Antworten:

101

Gibt es eine Möglichkeit, Typdeklarationen in GHCi bereitzustellen?

let numUniques' :: (Eq a) => [a] -> Int; numUniques' = length . nub

Oder gibt es eine andere Möglichkeit, solche Funktionen zu definieren, für die keine Typdeklarationen erforderlich sind?

Wenn Sie die Monomorphismus-Einschränkung mit deaktivieren -XNoMonomorphismRestriction, wird der richtige Typ abgeleitet.

sepp2k
quelle
3
Ich bin mit dem Monomorphismus noch nicht da, aber im Allgemeinen hat mich diese Antwort darauf hingewiesen, Semikolons zu verwenden, um Definitionen in GHCi zu gruppieren - Tutorials werden wie in einer .hs-Datei geschrieben, was beim Versuch in GHCi viele verschiedene Probleme verursacht (Funktionen sind nicht bindend usw. .).
Tomasz Gandor
Es ist erwähnenswert, dass -XNoMonomorphismRestrictionGHCi seit 7.8.1 standardmäßig aktiviert ist: downloads.haskell.org/~ghc/latest/docs/html/users_guide/…
N. Shead
13

Beachten Sie, dass Sie die Monomorphismusbeschränkung auch vermeiden können, indem Sie Ihrem Ausdruck einfach "Punkte" (dh explizite Variablen) hinzufügen. Das ergibt also auch den richtigen Typ:

let numUniques x = Länge. nub $ x

sclv
quelle
1
Danke - das ist toll zu wissen.
Mattbh
Dies ist als Eta-Erweiterung bekannt
Bladt
3

Das GHC-Benutzerhandbuch zeigt zwei zusätzliche Möglichkeiten, um dies zu erreichen. In diesem Unterabschnitt wird das Konstrukt :{... vorgestellt :}, das wie folgt verwendet werden kann:

> :{
| numUniques :: (Eq a) => [a] -> Int
| numUniques = length . nub
| :}

Alternativ können Sie den mehrzeiligen Modus aktivieren :

> :set +m
> let
| numUniques :: (Eq a) => [a] -> Int
| numUniques = length . nub
| 
Reinier Torenbeek
quelle