Wir können sehen, dass tails
ist eine Funktion, indem Sie den Typ überprüfen.
Um seinen Typ zu berechnen, beginnen wir mit dem Schreiben der Typen aller Zwischenfunktionen in der Komposition. Beachten Sie, dass wir für jeden Auftritt einer Funktion neue Typvariablen verwenden.
reverse :: [a] -> [a]
inits :: [b] -> [[b]]
map :: (c -> d) -> [c] -> [d]
Jetzt haben wir map reverse
[[e]] -> [[e]]
hat geben, da wir c=d=[e]
für irgendeine Art bekommen e
aus dem Vergleich der Ausdrücke
reverse :: c -> d -- for some c and d
reverse :: [e] -> [e] -- for some e
Daher sind die letzten beiden Zwischenprodukte haben Typen
map reverse :: [[e]] -> [[e]]
reverse :: [f] -> [f]
Jetzt beginnen wir Versuche, Typen zu vergleichen. Lassen Sie mich zuerst betonen, dass dies offensichtlich KEINE REALEN TYPEN sind! (Sorry für die alle Kappen, aber ich will jemand nicht entgehen lassen.)
inits . reverse :: [a] -*- [a] = [b] -*> [[b]]
-- I'm using a -*- b -*> c to denote the type a -> c obtained by
-- composing a function of type a -> b with one of type b -> c.
-- The *s are to break the double dashes up,
-- so they aren't parsed as a comment.
-- Anyway, looking at this type, we see
-- we must have [a] = [b], so a = b
-- we can rewrite the type of inits . reverse as
inits . reverse :: [a] -> [[a]]
dann für die nächste Zusammensetzung:
map reverse . inits . reverse :: [a] -*- [[a]] = [[e]] -*> [[e]]
-- again, we have [[a]] = [[e]], so e = a, and we have
map reverse . inits . reverse :: [a] -> [[a]]
Schließlich haben wir
reverse . map reverse . inits . reverse :: [a] -*- [[a]] = [f] -*> [f]
-- This time we have [[a]] = [f], so we must have f = [a], so the type
-- of the final composition is
tails = reverse . map reverse . inits . reverse :: [a] -> [[a]]
Da tails
den Typ [a] -> [[a]]
hat, muss es eine Funktion sein, die eine Liste von a
s als Argument akzeptiert und eine Liste mit Listen von a
s zurückgibt.
FYI, das ist ein * schrecklich ineffizient * Definition von 'tails'. Es würde zumindest etwas sinnvoller sein, "inits" in Bezug auf "tails" zu definieren, obwohl das auch nicht großartig wäre. "Tails", die richtig implementiert sind, sind von Natur aus viel effizienter als "Inits": "O (n)" und nicht "O (n^2)". – dfeuer
Ich bemerkte bereits, dass es von einigen Vortragsfolien war, so dass der Punkt darin bestand, ein neues Konzept zu illustrieren. Effizienz spielt hier keine Rolle. – markvdlaan93