Segunda Prova de LP2 - 98/1 ============================ 1 - (1.0) Avalie a expressao abaixo usando lazy evaluation (outermost) O resultado seria o mesmo se ela fosse avaliada de forma estrita (innermost)? Por que? take 2 (map (10 `div`) [-2..]) outermost: take 2 ((10 `div`) (-2) : map (10 `div`) [-1..]) (10 `div`) (-2) : take 1 (map (10 `div`) [-1..]) (10 `div`) (-2) : take 1 ((10 `div`) (-1) : map (10 `div`) [0..]) (10 `div`) (-2) : ((10 `div`) (-1) : take 0 (map (10 `div`) [0..])) (10 `div`) (-2) : ((10 `div`) (-1) : []) (-5) : (-10) : [] (i.e. [-5,-10]) innermost: entra em loop, pois nao consegue avaliar [-2..]. - Dado o tipo de dados de produtos de um supermercado abaixo, podemos ter produtos simples, com seu codigo e preco, produtos multiplos (caixa de refrigerantes, por exemplo) com seu codigo e sao compostos de um mesmo produto em uma determinada quantidade, e produtos compostos (cesta de natal) que possuem seu codigo mas sao na realidade uma lista de produtos. Uma lista de compras e' a lista dos codigos de cada produto comprado. type Code = Int type Quantity = Int type Price = Int type Name = String type ProductList = [Product] type ShoppingList = [Code] data Product = Simple Code Name Price | Multiple Code Name Product Quantity | Composite Code Name [Product] Faca funcoes para: 2 - (1.5) - criar uma nota da lista de compras, com o nome generico do produto e seu preco: makeBill :: ProductList -> ShoppingList -> [(Name,Price)] makeBill prl = map name_price . map (findProd prl) where name_price prod = (getname prod, prodPrice prod) getName (Simple _ n _) = n getName (Multiple _ n _ _) = n getName (Composite _ n _) = n getCode (Simple c _ _) = c getCode (Multiple c _ _ _) = c getCode (Composite c _ _) = c findProd (p:ps) code | code == getCode p = p | otherwise = findProd ps code 3 - (1.5) - calcule o preco de um produto prodPrice :: Product -> Int prodPrice (Simple c n p) = p prodPrice (Multiple c n pr q) = q * prodPrice pr prodPrice (Composite c n prl) = sum (map prodPrice prl) 4 - (1.5) - calcule o preco total de uma compra makeTotal :: ProductList -> ShoppingList -> Int makeTotal prl = sum . map snd . makeBill prl 5 - (1.5) - Faca tres funcoes que insiram um novo produto em uma productList. Note que sao dados como entrada os *codigos* dos produtos que compoe produtos multiplos/compostos! insSimple :: ProductList -> Code -> Name -> Price -> ProductList insSimple prl c n p = (Simple c n p) : prl insMultple :: ProductList -> Code -> Name -> Code -> Quantity -> ProductList insMultple prl c n c' qty = (Multiple c n (findProd prl c') qty) : prl insComposite :: ProductList -> Code -> Name -> [Code] -> ProductList insComposite prl c n cl = (Composite c n (map (findProd prl) cl)) : prl 6 - (1.5) - faca uma funcao que dobre o preco de um produto. doublePrice :: Product -> Product doublePrice (Simple c n p) = Simple c n (p*2) doublePrice (Multiple c n pr q) = Multiple c n (doublePrice pr) q doublePrice (Composite c n prl) = Composite c n (map doublePrice prl) 7 - (1.0) - Qual o principio de inducao que deveria ser usado se se quisesse provar propriedades sobre o tipo Product? i.e. qual/quais o(s) caso(s) a serem analisados (mostrar inicio da prova) e a(s) hipotese(s) assumida(s) para tentar provar, por exemplo, que 2 * prodPrice p == prodPrice (doublePrice p) caso base: provar (2 * prodPrice (Simple c n p)) == prodPrice (doublePrice (Simple c n p)) hipotese de inducao: para qualquer produto p, 2 * prodPrice p == prodPrice (doublePrice p) provar os casos: I) (2 * prodPrice (Multiple c n p q)) == prodPrice (doublePrice (Multiple c n p q)) e II) (2 * prodPrice (Composite c n ps)) == prodPrice (doublePrice (Composite c n ps)) (** II requer subprovas **) 8 - (1.0) - dada uma lista de compras criar uma lista de produtos comprados *detalhada*, i.e. apenas com produtos simples (em suas quantidades (repeticoes) corretas): makeDetailedList :: ProductList -> ShoppingList -> ProductList makeDetailedList prl = map detail . map (findProd prl) where detail :: Product -> [Product] detail (Multiple c n pr q) = (concat . take q . repeat . detail) pr detail (Composite c n prl) = (concat . map detail) prl detail simple = [simple]