Beh, siamo in grado di commentare il tipo Churchlist in questo modo per chiarire che:
-- Tell me...
type Churchlist t u = (t -> u -> u) -- ...how to handle a pair
-> u -- ...and how to handle an empty list
-> u -- ...and then I'll transform a list into
-- the type you want
Si noti che questo è intimamente legata alla funzione foldr
:
foldr :: (t -> u -> u) -> u -> [t] -> u
foldr k z [] = z
foldr k z (x:xs) = k x (foldr k z xs)
foldr
è una funzione molto generale che può implementare ogni sorta di altre funzioni di lista. Un esempio banale che vi aiuterà sta attuando una copia elenco con foldr
:
copyList :: [t] -> [t]
copyList xs = foldr (:) [] xs
Uso del tipo sopra commentata, foldr (:) []
significa questo: "se vedi un elenco vuoto restituisce la lista vuota, e se si vede una coppia restituire head:tailResult
. "
Utilizzando Churchlist
, si può facilmente scrivere la controparte in questo modo:
-- Note that the definitions of nil and cons mirror the two foldr equations!
nil :: Churchlist t u
nil = \k z -> z
cons :: t -> Churchlist t u -> Churchlist t u
cons x xs = \k z -> k x (xs k z)
copyChurchlist :: ChurchList t u -> Churchlist t u
copyChurchlist xs = xs cons nil
Ora, per implementare map
, basta sostituire cons
con una opportuna funzione, in questo modo:
map :: (a -> b) -> [a] -> [b]
map f xs = foldr (\x xs' -> f x:xs') [] xs
La mappatura è come copiare un elenco, tranne per il fatto che anziché copiare semplicemente gli elementi alla lettera si applica f
a ciascuno di essi.
Studia tutto con attenzione, e dovresti essere in grado di scrivere mapChurchlist :: (t -> t') -> Churchlist t u -> Churchlist t' u
da solo.
esercizio supplementare (facile): scrivere queste funzioni lista in termini di foldr
, e scrivere le controparti per Churchlist
:
filter :: (a -> Bool) -> [a] -> [a]
append :: [a] -> [a] -> [a]
-- Return first element of list that satisfies predicate, or Nothing
find :: (a -> Bool) -> [a] -> Maybe a
Se ti senti come affrontare qualcosa di più difficile, provare a scrivere tail
per Churchlist
. (Inizia scrivendo tail
per [a]
utilizzando foldr
.)
la pagina [encoding Chiesa] (https://secure.wikimedia.org/wikipedia/en/wiki/Church_encoding#List_encodings) su wikipedia sembra un buon punto di partenza a partire dal. –
@jcdmb: studi informatica al KIT? –