2016-11-15 2 views
1

Ich bin neu in Haskell, also könnte das eine dumme Frage sein. Ich lese ein Buch, wo es heißt :type sum soll sum :: (Num a) => [a] -> a zeigen. Stattdessen lautet die Nachricht sum :: (Num a, Foldable t) => t a -> a. Wie ich in https://www.haskell.org/hoogle/?hoogle=Sum gesehen habe, liegt dieser Unterschied in der Existenz von zwei verschiedenen Summenfunktionen. Vielleicht ist es so etwas wie Polymorphismus in Java, ich fange gerade an und ich habe keine Ahnung wie Haskell funktioniert.Verschiedene Typen in der Summenfunktion

Also meine Fragen sind: Wie könnte ich die Summenfunktion verwenden, die sum :: (Num a) => [a] -> a statt der anderen ist? Kannst du mir erklären, was hier vor sich geht?

+0

Die Liste 'sum' befindet sich in' Prelude', d. H. Standardmäßig im Bereich. Wenn Sie also nichts Spezielles tun, werden Sie es verwenden. Um auf eine andere "Summe" zu verweisen, müssen Sie "Data.Foldable" importieren. Also, was genau sind deine Zweifel? Wenn es Unklarheiten gibt, sollte der Compiler darüber berichten. – laughedelic

+3

@laughedelic Das Prelude 'sum' ist seit den letzten GHC-Releases identisch mit dem von' Data.Foldable'. – duplode

+4

Seit GHC 7.10 haben einige Funktionen im Prelude verallgemeinerte Signaturen. Es gibt nicht mehr eine Summe :: Num a => [a] -> a' - die neue 'Summe :: (Num a, Faltbare t) => ta -> a' funktioniert immer noch auf Listen (wie die alte)) aber es funktioniert jetzt auch an anderen Dingen ([Sequenzen] (https://hackage.haskell.org/package/containers-0.5.8.1/docs/Data-Sequence.html) oder [Sets] (https: // hackage .haskell.org/package/containers-0.5.8.1/docs/Data-Set.html)) – Alec

Antwort

2

Wie ich in https://www.haskell.org/hoogle/?hoogle=Sum gesehen habe, ist dieser Unterschied wegen -Ich denke- die Existenz von zwei verschiedenen Summenfunktionen. Vielleicht ist es so etwas wie

Polymorphismus in Java

Es ist in der Tat, Polymorphismus, wenn auch nicht in dieser Art und Weise (den P. S. am Ende dieser Antwort sehen). Beachten Sie, dass ...

sum :: (Num a) => [a] -> a 

... ist bereits polymorphe in der Art der Zahlen summiert werden, so dass es mit funktionieren würde, zum Beispiel Listen von Integer und Listen von Double. Der Unterschied zwischen diesem und ...

sum :: (Num a, Foldable t) => t a -> a 

... ist, dass diese sum in der Art des Behälter auch polymorph:

GHCi> -- +t makes GHCi print the types automatically. 
GHCi> :set +t 
GHCi> sum [1 :: Integer, 2, 3] 
6 
it :: Integer 
GHCi> sum [1 :: Double, 2, 3] 
6.0 
it :: Double 
GHCi> import qualified Data.Set as S 
GHCi> :t S.fromList 
S.fromList :: Ord a => [a] -> S.Set a 
GHCi> sum (S.fromList [1 :: Double, 2, 3]) 
6.0 
it :: Double 

Für einen Containertyp mit sum verwendet werden Es muss eine Instanz von the Foldable class enthalten, die Funktionen abdeckt, die wie sum ausgedrückt werden können, indem der Container in eine Liste abgeflacht und dann irgendwie gefaltet wird.

S.S .: Ihr Buch sagt etwas anderes als das, was Sie gesehen haben, denn bis vor kurzem hatte die sum Funktion im Prelude einen weniger allgemeinen, listenspezifischen Typ und Ihr Buch ist älter als die Änderung. Zwei verschiedene Funktionen namens sum, auch wenn eine streng allgemeinere als die andere ist, würde zu einem Namenskonflikt führen (aus einem ähnlichen Grund, dass ich das im obigen Beispiel qualifizierte Modul Data.Set importierte), ist es eine gute Idee tun Sie dies, weil es einige Funktionen wie map definiert, die mit Prelude-Funktionen kollidieren, und sie beispielsweise mit S.map ausschließen, um Probleme zu vermeiden.

Verwandte Themen