stavo sperimentando con Haskell, e durante il tentativo di migliorare la leggibilità del mio codice ho improvvisamente cambiato il comportamento di esso. Avrei pensato che queste due varianti sarebbero equivalenti.Perché queste funzioni in modo diverso valutati
originale:
f :: Eq c => c -> c -> [[c]] -> [[c]]
f d c acc
| c == d = [] : acc
| otherwise = ([c] ++ (head acc)) : tail acc
split :: Eq a => a -> [a] -> [[a]]
split delim = foldr (f delim) [[]]
Ecco il secondo:
f' :: Eq c => c -> c -> [[c]] -> [[c]]
f' d c (currentWord:wordsSoFar)
| c == d = [] : currentWord : wordsSoFar
| otherwise = (c : currentWord) : wordsSoFar
split' :: Eq a => a -> [a] -> [[a]]
split' delim = foldr (f' delim) [[]]
Ecco i risultati dell'esecuzione del due:
*Main> take 1 (split 5 [1..])
[[1,2,3,4]]
*Main> take 1 (split' 5 [1..])
*** Exception: stack overflow
nel tuo secondo codice prova a cambiare 'split'' a' split' – maioman
@maioman Che non risponde a nulla. – Jubobs
'foldr' è un tipo di cosa" magica "che genera una ricorsione molto profonda, ma poi viene ottimizzata (o meno) dal compilatore. Ti suggerirei di provare a riscrivere il tuo codice in termini di 'foldl'', che funziona a profondità di ricorsione lineare. La grande differenza in due esempi è che il primo 'f' non esamina è' acc' su richiesta. –