2014-07-06 7 views
6

Rispondendo a questo question, mi sono reso conto che Haskell consente di decostruire l'oggetto quando si dichiara la funzione e utilizzarlo per eseguire definizioni di funzioni parallele.La dichiarazione parallela di funzione è una buona idea?

In sostanza, immaginiamo mi piacerebbe fare qualcosa di simile

a = (1+) 
b = (2+) 
c = (3+) 
d = (4+) 
e = (5+) 

Quale sarebbe il modo più secco di scriverlo? Voglio dire, dopo tutto il modello è lo stesso: il nome della funzione non può essere indovinato né l'ammontare da aggiungere, ma dovrei essere in grado di evitare di scrivere ogni volta + (senza usare Template Haskell ovviamente).

Fondamentalmente, mi piacerebbe essere in grado di utilizzare map o qualcosa di simile e sembra che map funziona solo !.

[a,b,c,d,e] = map (+) [1..5] 

Et voilà!

Questo è molto più breve e forse più espressivo, e funziona:

> a 10 
11 
> b 10 
12 
etc ... 

Quindi la mia domanda è, è un buon modello da utilizzare (in questo tipo di situazione) e se non, che sono il sorteggio back (lo so acquistare esperienza che l'equivalente in Ruby è un incubo, ma le ragioni non sembra applicarsi con Haskell)?

Aggiornamento

Capisco la leggibilità di tale codice è soggettiva e può essere visto come base-opinione. Tuttavia, potrebbero esserci alcune ragioni obiettive per non farlo. Ad esempio, in Ruby (almeno 1.8), i metodi definiti utilizzando define_method non sono visibili per la maggior parte degli sviluppatori di IDE e tag. Inoltre, non è possibile intervenire con il debugger ecc., Cosa che li rende davvero scomodi nella pratica. Sto chiedendo motivo simile in Haskell

+7

Questa domanda sta attirando voti ravvicinati "principalmente basati sull'opinione pubblica" - anche se penso che ci sia un grado di soggettività nella domanda, è ancora capace di una risposta ragionevolmente obiettiva e dovrebbe essere lasciata aperta. –

risposta

8

Uno svantaggio con

[a,b,c,d,e] = map (+) [1..5] 

è che richiede non esaustivo pattern-matching - la partita non è garantita in modo statico per essere valido. Ovviamente in questo caso non ci sono problemi, ma in un esempio più sottile in cui forse [1..5] è stato definito altrove, potrebbe essere più difficile da vedere.

Anche in questo caso non vedo alcun vantaggio particolare in questo stile, anche se mi rendo conto che è un esempio un po 'forzato.

un caso in cui la definizione di valori multipli in una singola riga è utile è se si dispone di una funzione che restituisce una tupla, per esempio:

(xs, ys) = unzip [(1, 'a'), (2, 'b')] 
+1

Il disordine non esaustivo potrebbe essere parzialmente risolto scrivendo 'a: b: c: d: e: _ = map (+) [1 ..]' –

6

Questo può essere realizzato utilizzando il pacchetto per homogeneous tuples (che sono l'autore di):

import Data.Tuple.Homogenous 

... 
    let Tuple4 (a, b, c, d) = fmap (+) $ Tuple4 (1, 2, 3, 4) 
    in ... 

senza ricorrere alla corrispondenza del modello non esaustivo.

Inoltre, esiste un altro pacchetto simile tup-functor.