Zu (1): Das ist die Typsignatur von join, die man eigentlich auch weglassen könnte, es aber zur Klarheit des Codes beiträgt(Haskell kann den Typ einer Funktion meistens selbst ableiten(Stichwort: type inference)). Show ist eine sog. type class, teilweise vergleichbar mit Interfaces aus Java; Concepts in C++ sind genau dieses Feature direkt aus Haskell übernommen. Jeder Datentyp dieser Typklasse stellt u.a. die Funktion show zu Verfügung, die aus dem Datentyp einen String macht, z.B. show 1 == "1". Durch Show a => .. sagt man aus, dass diese Funktion für jeden Typ a definiert ist, der eine Instanz von Show ist. Der erste Parameter ist ein String, der zweite vom Typ a und das Ergebnis wieder vom Typ String(Genau genommen hat jede Funktion in Haskell nur 1 Parameter und gibt dann quasi eine weitere Funktion zurück(Stichwort: currying)).
Zu (2): intersperse hat den Typ a -> [a] -> [a]. Das heißt, es nimmt ein Element eines beliebigen Typs a, eine Liste aus as und gibt eine Liste aus as zurück. In diesem Fall fügt es zwischen die Elemente der Liste jeweils den ersten Parameter ein. Der '.'-Operator ist im Grunde das selbe wie der Punkt-Operator zur Verkettung von Funktionen aus der Mathematik. Der '$'-Operator wendet die Funktion links von ihm auf das Argument rechts an und wird hier nur von mir verwendet um Klammern zu vermeiden, was möglich ist, da der Operator eine besonders niedrige Präzedenz hat(Man kann in Haskell Operatoren und ihre "Bindungsstärke" selbst definieren). Ebenso gültig wäre:
Code:
concat (intersperse delim (map show xs))
Aber für einen Nicht-LISPer wird sowas schnell weniger lesbar als die erste Variante. "concat . intersperse delim" verkettet also concat und intersperse delim(Interessant ist hier auch die teilweise Anwendung von intersperse, die dann wieder eine Funktion zurückgibt) und liefert somit eine Funktion die zuerst intersperse delim auf das Argument und dann concat auf das Ergebnis dessen anwendet. Beispiel:
concat . intersperse ", " $ ["1","2"]
==
concat (intersperse ", " ["1","2"])
==
concat ["1",", ","2"]
==
"1, 2"
show wandelt seinen Parameter in einen String um, wenn der Typ des Parameters Instanz der Typklasse Show ist, ersichtlich am Typ von show:
Show s => s -> String.
Das "=>" kann man damit als so eine Art Implikation wie aus der Mathematik verstehen. Aus der Zugehörigkeit des Typs s zu Show folgt eine Funktion mit Typ s -> String. Durch map show xs macht man also aus der übergebenen Liste aus as eine Liste aus Strings, was nötig ist, da man bei intersperse einen String in diese einfügen will und Listen in Haskell immer aus Elementen eines Typs bestehen.
Neben zahlreichen Texten, gibt es auch einen Vortrag in dem diese Sachen sehr gut erläutert werden:
http://blip.tv/file/324976 und
http://blip.tv/file/325646