Mentre studiavo più profondo Applicative
sono venuto a Traversable
, anche se conoscevo già Foldable
da LYHGG, non ho visto il primo ancora, quindi ho iniziato a leggere il Haskell wiki about Traversable.pieghevole vs Traversable
Durante la lettura ho capito perché Foldable.fold
è parallelo a Traversable.sequenceA
e Foldable.foldMap
è parallelo a Traversable.traverse
.
ho visto anche che ogni Traversable
è anche un Foldable
e un Functor
e sequenceA
e traversal
dispone di un'implementazione di default in termini di vicenda:
traverse f = sequenceA . fmap f
sequenceA = traverse id
Quindi, come ho visto in LYHGG che foldMap
è una definizione completa minima per Foldable
, ho pensato che è parallela a traverse
, quindi fold
(che è parallela a sequenceA
) sarebbe anche una definizione completa minima (che non lo è) ... Foldable
non è un Functor
come Traversable
è, quindi non possiamo applichiamo questo:
foldMap f = fold . fmap f
fold = foldMap id -- this is ok
Perché non è ogni Foldable
un Functor
, e che sarebbe un esempio di Foldable
che in realtà non è un Functor
?
'Set' è un classico esempio di' Pieghevole' che non è un 'Functor'. Così sono i vettori unboxed. – dfeuer
@dfeuer Leggerò di più su 'Set' per capire perché non è un' Functor', ma, Sets possono essere pensati come contenitori di cose che non si ripetono ... Detto questo, non riesco a capire rapidamente perché non è un'istanza di 'Functor' ... – FtheBuilder
Il problema è che 'Functor' non dà alle implementazioni l'opportunità di limitare i loro argomenti di tipo. Immagina se qualcuno abbia scritto 'fmap f s' dove' f :: Int -> Integer -> Integer'. Il tipo "Integer -> Integer" non è nemmeno un'istanza di "Eq", tanto meno "Ord", quindi non c'è modo di verificare la presenza di duplicati durante la mappatura. La funzione potrebbe mappare più elementi a funzioni identiche e non avresti modo di comprimere i duplicati. – dfeuer