[Rio-pm] [Golf] Função drop Haskell

Daniel de Oliveira Mantovani daniel.oliveira.mantovani em gmail.com
Quinta Fevereiro 4 02:41:38 PST 2010


2010/2/3 Daniel de Oliveira Mantovani <daniel.oliveira.mantovani em gmail.com>:
> 2010/2/3 Eden Cardim <edencardim em gmail.com>:
>>>>>>> "Daniel" == Daniel de Oliveira Mantovani <daniel.oliveira.mantovani em gmail.com> writes:
>>
>>    Daniel> Eu fiz em Perl, para ficar claro:
>>
>>    Daniel> <perl> sub drop { my ( $n, $xs ) = @_; if ( ref $_[1] ne
>>    Daniel> 'ARRAY' ) { $n <= 0 ? return $_[1] : return substr( $_[1],
>>    Daniel> $n );
>>    Daniel>     }
>>    Daniel>     if ( $n <= 0 || !@_ ) { return @{$xs};
>>    Daniel>     }
>>    Daniel>     else { shift @{$xs}; drop( ( $n - 1 ), $xs );
>>    Daniel>     }
>>    Daniel> }
>>    Daniel> </perl>
>>
>> Só a título de curiosidade:
>> Na verdade, não é isso que acontece no caso de Haskell. A função drop
>> do Prelude tem o tipo Int -> [a] -> [a], que significa que ela recebe um
>> inteiro, e uma lista de qualquer tipo e retorna outra lista do mesmo
>> tipo.
>
> Exatamente é uma função do tipo polimórfica.
>
>  Strings em Haskell são arrays de caracteres (não um tipo como em
>> perl), então qualquer operação de lista é aplicável a uma string, C
>> também é assim. Logo, em perl a função seria algo como:
>>
>>    sub drop{$s=shift;splice(@_,- em _+$s)}
>>
>> print drop(2, 1..5);
>> 345
>> print drop(1, 1..5);
>> 2345
>> print drop()
>>
>> E mesmo assim isso não é equivalente porque splice modifica a lista
>> in-place, a modificação do @_ se propaga pro escopo do invocador da
>> função, e funções em haskell são imutáveis, etc...
>
> Você está certo, seria impossível fazer como Haskell faz, eu fui muito
> genérico e não expliquei de fato o que. Me parece que todos entenderão
> a idéia.
>
>>
>> Mas enfim, vamos à tacada:
>>
>> sub drop{($s,$_)=@_;$_=[split//]if!ref;splice(@$_,-@$_+$s)}
>
> Sua tacada não funciona com números negativos.
> [mantovani em localhost ~/Perl/Funcional]$ perl -MHaskell -E 'say $_ for
> drop(-1,[1,2,3,4,5])'
> Modification of non-creatable array value attempted, subscript -6 at
> Haskell.pm line 7.

Na verdade eu falei com o Eden no IRC, e ele está certo. Em Haskell o
"-" é um operador unário.
A função drop em Haskell é:

Prelude> drop 1 [1..5]
[2,3,4,5]

Porém quando o número é negativo precisa colocar entre parênteses:
Prelude> drop (-1) [1..5]
[1,2,3,4,5]

Se não o Haskell entende que é um operador não um número negativo.
Prelude> 10 + (-2)
8

E se você executar a tacada do Eden como em Haskell com (-1) ao invés
de -1 funciona.


>
> Funciona quando é positivo:
> [mantovani em localhost ~/Perl/Funcional]$ perl -MHaskell -E 'say $_ for
> drop(1,[1,2,3,4,5])'
> 2
> 3
> 4
> 5
>
>>
>> 60
>>
>> --
>>   Eden Cardim       Need help with your Catalyst or DBIx::Class project?
>>  Code Monkey                    http://www.shadowcat.co.uk/catalyst/
>>  Shadowcat Systems Ltd.  Want a managed development or deployment platform?
>> http://edenc.vox.com/            http://www.shadowcat.co.uk/servers/
>>
>> _______________________________________________
>> Rio-pm mailing list
>> Rio-pm em pm.org
>> http://mail.pm.org/mailman/listinfo/rio-pm
>>
>
>
>
> --
> "If you’ve never written anything thoughtful, then you’ve never had
> any difficult, important, or interesting thoughts. That’s the secret:
> people who don’t write, are people who don’t think."
>



-- 
"If you’ve never written anything thoughtful, then you’ve never had
any difficult, important, or interesting thoughts. That’s the secret:
people who don’t write, are people who don’t think."


Mais detalhes sobre a lista de discussão Rio-pm