Cuantificadores sobre listas
Definir la función
verificaP :: (a -> Bool) -> [[a]] -> Bool
tal que (verificaP p xs) se verifica si cada elemento de la lista xss contiene algún elemento que cumple el predicado p. Por ejemplo,
verificaP odd [[1,3,4,2], [4,5], [9]] == True verificaP odd [[1,3,4,2], [4,8], [9]] == False
Soluciones
import Test.Hspec (Spec, describe, hspec, it, shouldBe) import Test.QuickCheck.HigherOrder -- 1ª solución -- =========== verificaP1 :: (a -> Bool) -> [[a]] -> Bool verificaP1 p xss = and [any p xs | xs <- xss] -- 2ª solución -- =========== verificaP2 :: (a -> Bool) -> [[a]] -> Bool verificaP2 _ [] = True verificaP2 p (xs:xss) = any p xs && verificaP2 p xss -- 3ª solución -- =========== verificaP3 :: (a -> Bool) -> [[a]] -> Bool verificaP3 p = foldr ((&&) . any p) True -- 4ª solución -- =========== verificaP4 :: (a -> Bool) -> [[a]] -> Bool verificaP4 p = all (any p) -- 5ª solución -- =========== verificaP5 :: (a -> Bool) -> [[a]] -> Bool verificaP5 = all . any -- Verificación -- ============ verifica :: IO () verifica = hspec spec specG :: ((Int -> Bool) -> [[Int]] -> Bool) -> Spec specG verificaP = do it "e1" $ verificaP odd [[1,3,4,2], [4,5], [9]] `shouldBe` True it "e2" $ verificaP odd [[1,3,4,2], [4,8], [9]] `shouldBe` False spec :: Spec spec = do describe "def. 1" $ specG verificaP1 describe "def. 2" $ specG verificaP2 describe "def. 3" $ specG verificaP3 describe "def. 4" $ specG verificaP4 describe "def. 5" $ specG verificaP5 -- La verificación es -- λ> verifica -- 10 examples, 0 failures -- Comprobación de equivalencia -- ============================ -- La propiedad es prop_equivalencia :: (Int -> Bool) -> [[Int]] -> Bool prop_equivalencia p xss = all (== verificaP1 p xss) [verificaP2 p xss, verificaP3 p xss, verificaP4 p xss, verificaP5 p xss] -- La comprobación es -- λ> quickCheck' prop_equivalencia -- +++ OK, passed 100 tests. -- Comparación de eficiencia -- ========================= -- La comparación es -- λ> verificaP1 even [[x,x+2..x+10] ++ [0] | x <- [1,3..3000001]] -- True -- (2.11 secs, 4,308,601,216 bytes) -- λ> verificaP2 even [[x,x+2..x+10] ++ [0] | x <- [1,3..3000001]] -- True -- (2.32 secs, 4,224,602,000 bytes) -- λ> verificaP3 even [[x,x+2..x+10] ++ [0] | x <- [1,3..3000001]] -- True -- (1.87 secs, 4,080,601,088 bytes) -- λ> verificaP4 even [[x,x+2..x+10] ++ [0] | x <- [1,3..3000001]] -- True -- (1.81 secs, 4,068,601,008 bytes) -- λ> verificaP5 even [[x,x+2..x+10] ++ [0] | x <- [1,3..3000001]] -- True -- (1.76 secs, 4,068,601,152 bytes)