primer lugar quisiera reescribir su función un poco, ya
isListOk :: Bool
isListOk = length (filter isItemOk [1 .. 1000]) <= 3
es sin duda más idiomática de su versión. (Tenga en cuenta que también he cambiado la firma tipo que el suyo era incorrecto. Por otra parte, debería haber escrito 1 .. 1000
en lugar de 1.1000
.)
La evaluación perezosa es su mejor amigo aquí, ya que por lo general asegurarse de que no hay cálculos innecesarios serán realizado.
Desafortunadamente, su uso de length
(o el mapeo de cada elemento de una lista a 1 y luego sumar la lista resultante, como lo hace) se interpone en el camino aquí. Es decir, length
es estricto en el lomo de la lista: solo puede producir la longitud de la lista si la evalúa hasta el final, lo que, en este caso, significa que su programa tendrá que ejecutar su cheque mil veces .
Una solución sería combinar el cálculo de la longitud (es decir, El recorrido de la columna vertebral de la lista) y la prueba si la longitud calculada no supera un determinado umbral en una sola función que es, de hecho, perezoso en la columna vertebral de la lista de parámetros:
isNotLongerThan :: [a] -> Integer -> Bool
isNotLongerThan [] n = n >= 0
isNotLongerThan (_ : xs) n = n >= 1 && isNotLongerThan xs (n - 1)
y luego escribir
isListOk :: Bool
isListOk = filter isItemOk [1 .. 1000] `isNotLongerThan` 3
Para una solución reutilizable, puede, por supuesto, tanto abstracto sobre el predicado y el umbral:
forNoMoreThan :: (a -> Bool) -> Integer -> [a] -> Bool
forNoMoreThan p n = (`isNotLongerThan` n) . filter p
isListOk :: Bool
isListOk = (isItemOk `forNoMoreThan` 3) [1 .. 1000]
Por último, como señala Hammar, si su trillaste viejo es lo suficientemente pequeño y fijo, simplemente puede usar la coincidencia de patrones para determinar si una lista es lo suficientemente corta.
Su función no se verá más allá de 4 ya que 'take' y' list understandhension' son flojos. Intenta usar 'Int' si sabes que tu número no crecerá más allá del límite, ya que es mucho más rápido que' Integer'. Es 'Bool' y no' Boolean'. 'isListOk' debería tomar un argumento de lista. – Satvik