Estou tentando fazer esta pergunta do meu dever de casa:
Dado arbitrário
foo :: [[a]] -> ([a], [a])
, escreva uma lei que a funçãofoo
satisfaça, envolvendomap
listas e pares.
Algum contexto: Eu sou o primeiro ano de graduação fazendo um curso de programação funcional. Embora o curso seja bastante introdutório, o palestrante mencionou muitas coisas dos conteúdos programáticos, entre as quais os teoremas livres. Então, depois de tentar ler o artigo de Wadler, deduzi que, concat :: [[a]] -> [a]
com a lei, map f . concat = concat . map (map f)
parece relevante para o meu problema, já que precisamos ter foo xss = (concat xss, concat' xss)
onde concat
e onde concat'
houver funções do tipo [[a]] -> [a]
. Então foo
satisfaz bimap (map f, map g) . foo = \xss -> ((fst . foo . map (map f)) xss, (snd . foo . map (map g)) xss)
.
Essa "lei" já parece longa demais para ser correta, e também não tenho certeza da minha lógica. Então, pensei em usar um gerador de teoremas gratuitos on-line , mas não entendi o que lift{(,)}
significa:
forall t1,t2 in TYPES, g :: t1 -> t2.
forall x :: [[t1]].
(f x, f (map (map g) x)) in lift{(,)}(map g,map g)
lift{(,)}(map g,map g)
= {((x1, x2), (y1, y2)) | (map g x1 = y1) && (map g x2 = y2)}
Como devo entender essa saída? E como devo derivar a lei para a função foo
corretamente?
(\(a,b) -> (map f a, map f b)) . foo = foo . map (map f)