2013-10-11 12 views
12

Kürzlich habe ich einen Blick auf Haskell mit LYAH.Haskell warum benötigt "Num x" "Show x"?

Ich wurde um mit Typklassen Messing und schrieb diese Schnelltest-Funktion:

foo :: (Num x) => x -> String 
foo x = show x ++ "!" 

Aber das erzeugt diesen Fehler:

test.hs:2:9: 
    Could not deduce (Show x) arising from a use of `show' 
    from the context (Num x) 
    bound by the type signature for foo :: Num x => x -> String 
    at test.hs:1:8-29 
    Possible fix: 
     add (Show x) to the context of 
     the type signature for foo :: Num x => x -> String 

Aber nach Lyah:

To join Num, a type must already be friends with Show and Eq.

Also wenn alles in Num eine Teilmenge von Show undist, warum muss ich die Typensignatur in foo :: (Num x, Show x) => x -> String ändern, damit dies funktioniert? Kann man nicht schlussfolgern, dass ein Num auch Showable ist?

Antwort

18

Die Informationen in LYAH sind alt. Die release notes for GHC 7.4.1 sagen, dass:

The Num class no longer has Eq or Show superclasses.

Sie schreiben müssen,

foo :: (Num x, Show x) => x -> String 

(In der Tat, die foo Sie schrieb nicht Num x erfordert, so dass Sie, dass weglassen kann eine unnötige Einschränkung zu vermeiden.

)
+1

Welche Unterklassen von 'Num' _don't_ haben' Eq' oder 'Show' nicht mehr? Ich sehe keine Listen darüber, was diese gewonnen hat (oder warum es überhaupt geändert wurde.) – charmlessCoin

+6

Früher war es "Klasse (Eq a, Zeige ein)" => Num a where {...}, jetzt es ist nur 'Klasse Num a wo {...}'. Es gab keine Notwendigkeit, 'Eq' und' Show' als Oberklasse zu haben: eine 'Num'-Instanz impliziert keine Instanz einer dieser Klassen (wie' Ord' impliziert 'Eq'), noch hängt es von ihnen ab ("Num" hat keine Gesetze, und die Standarddefinitionen für seine "Methoden" beziehen sich nicht auf "Eq" oder "Show". Ich denke, deshalb wurde Num eine eigenständige Klasse. Weniger Anforderungen bedeutet, dass die Klasse mehr Instanzen zulässt, z. B. "Num b => Num (a -> b)". –

+3

Es ist wichtig zu beachten, dass dies eine GHC-Änderung ist; Der Haskell-Standard verlangt immer noch "Show" - und "Eq" -Klassen.Im engeren Sinne macht dies GHC zu einem nicht Haskell-kompatiblen Compiler; Diese Änderung wird jedoch höchstwahrscheinlich ihren Weg in den nächsten Standard finden, ähnlich wie "Applicative" bald eine Superklasse von "Monad" sein wird. – David

1

Sollten Sie nicht schreiben:

(Num x) => x -> String 

Statt

(Num x) x -> String 

Und soweit ich weiß, das Erbe ist zumindest überholt.

3

Es used to be, das eine Instanz von Num war auch eine Instanz von Show und Eq, aber das ist no longer the case.

Sie müssen auch eine Show Einschränkung hinzufügen.

3

Haskell, beide 98 und 2010 beide erfordern alle Instanzen von Num auch Instanzen in Show und Gl. Dies ist weitgehend ein Zufall der Geschichte.

GHC, der populärste Haskell-Compiler, weicht hier vom Standard ab, ohne dass ein Pragma benötigt wird. Dies wurde gemacht, um es anwendbaren Funktoren zu erlauben, Instanzen von Num zu sein und die Vorteile der überladenen Syntax zu genießen.