Skip to content

Instantly share code, notes, and snippets.

@juanedi
Last active August 29, 2015 14:20
Show Gist options
  • Save juanedi/41082e1cec993a11f158 to your computer and use it in GitHub Desktop.
Save juanedi/41082e1cec993a11f158 to your computer and use it in GitHub Desktop.
foldlBreak
{-
implementación de fold' según https://wiki.haskell.org/Foldr_Foldl_Foldl'
-}
foldl' :: (b -> a -> b) -> b -> [a] -> b
foldl' f z [] = z
foldl' f z (x:xs) = let z' = f z x
in seq z' $ foldl' f z' xs
{-
similar a foldl pero con un predicado que sirve para parar la recursión
si se llega a un resultado que sabemos que no va a cambiar.
espero que lo hayas resuelto por tu cuenta antes!
¿usaste seq? ¿o directamente un if? ¿por qué?
-}
foldlBreak :: (b -> Bool) -> (b -> a -> b) -> b -> [a] -> b
foldlBreak stop f z [] = z
foldlBreak stop f z (x:xs) = let z' = f z x
in seq z' $
if stop z'
then z'
else foldlBreak stop f z' xs
{-
implementaciones de "todos menores a 2" con las distintas "versiones" de fold
-}
tm2LBreak :: [Integer] -> Bool
tm2LBreak = foldlBreak not (\z x -> z && x < 2) True
-- en este caso puntual la función "combinadora" podría ignorar el resultado
-- actual porque sabemos que va a ser True y no tiene sentido hacer True && (x < 2)
tm2L :: [Integer] -> Bool
tm2L = foldl (\z x -> z && x < 2) True
tm2L' :: [Integer] -> Bool
tm2L' = foldl' (\z x -> z && x < 2) True
tm2R :: [Integer] -> Bool
tm2R = foldr (\x rec -> (x>2) && rec) True
{-
ejercicio!
hacé predicciones de cómo se van a comportar las siguientes expresiones al ser evaluadas y después
contrastá utilizando algún programa para ver el uso de memoria y el tiempo que tardan en retornar
el resultado.
-}
test f = let x = 1000000000000000000000000 in f [x,(x-1)..]
testLBreak = test tm2LBreak
testL = test tm2L
testL' = test tm2L'
testR = test tm2R
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment