Em Thinking Functionally with Haskell (p 45), Richard Bird diz que existem seis funções com type Maybe a -> Maybe a
, embora ele cite apenas cinco.
Aplicado à
Nothing
função só pode retornarNothing
ouundefined
. Aplicado àJust x
função só pode retornarNothing
ouJust x
ouundefined
. A questão é que não sabemos absolutamente nada sobre o tipo subjacente, portanto nenhum valor novo pode ser inventado. Isso perfaz seis funções possíveis ao todo.
Eu conto sete:
first, second, third, fourth, fifth, sixth, seventh :: Maybe a -> Maybe a
first (Just x) = Just x
second (Just x) = Nothing
third (Just x) = undefined
fourth Nothing = Nothing
fifth Nothing = undefined
sixth undefined = Nothing
seventh undefined = undefined
Um quebra-cabeça relacionado é que quando tento colocar três dessas definições em uma única função, recebo um erro de compilação "A correspondência de padrão é redundante". Remover qualquer uma das três linhas faz com que ela desapareça
foo :: Maybe a -> Maybe a
foo (Just x) = Nothing
foo Nothing = undefined
foo undefined = Nothing
Suas funções não são funções totais e cada vez tomam um caso. Isso significa que o caso que não está coberto, erros.
então, essencialmente, se você escrever:
isso é:
Portanto, você precisa cobrir os dois casos combinados:
Just x
, ouNothing
e assim multiplicar as possibilidades de cada caso.Outro problema é que
undefined
in nãosixth undefined = Nothing
verifica se o item está indefinido: é apenas uma variável chamada . Então é equivalente a .undefined
sixth x = Nothing
Isso nos deixa essencialmente com três opções para
Just x
:Just x
,Nothing
eundefined
/error
, e duas opções paraNothing
:Nothing
e indefinido, então:No entanto, estas não são todas as opções: você também pode retornar
Just undefined
(ouJust (error "<undefined>")
) para qualquer um dos dois casos. Deixo listá-los como um exercício.