a
rappresenta il tipo del valore dell'accumulatore e b
rappresenta il tipo di ciascun elemento nell'input. (a -> b -> a)
è una funzione che accetta un valore di accumulatore, una voce nell'elenco e restituisce un nuovo valore di accumulatore che può essere passato al passaggio successivo.
Il tipo del valore iniziale deve essere a
in modo che la prima chiamata della funzione possa ricevere un valore di accumulatore. La funzione di accumulatore deve prendere un a
e restituire un a
in modo che un valore di accumulatore possa essere passato a ciascun passo della piega. Il valore finale della piega deve necessariamente essere un a
, perché quello è il tipo dell'accumulatore che verrà restituito dalla chiamata finale alla funzione di piega.
(a -> b -> c) -> a -> [b] -> c
non può rappresentare una piega, poiché la funzione di piegatura non richiede un c
. L'input e l'output della funzione di piegatura devono essere dello stesso tipo in modo che l'accumulatore possa essere passato al passaggio successivo.
Vediamo un esempio di cosa accadrebbe se la funzione di piegatura restituisse un c
.
f :: Integer -> Integer -> Bool -- this is a valid (a -> b -> c)
f acc n = (acc + n) > 0
Fingere che stiamo usando un linguaggio dinamico e cerchiamo di piegare con f
. Cosa succede al runtime?
foldl f 0 [1] ~ (0 + 1) > 0 == True :: Bool
foldl f 0 [1, 2] ~ ((0 + 1) > 0) + 2) > 0 == error - no instance of (+) for Bool
\_________/ \
| \
Bool + Integer
Si può vedere che non è possibile eseguire una piegatura se si tenta di accumulare con tipi incompatibili.
fonte
2013-02-08 08:57:35
grazie Chris! questo è utile. – user342673