2013-06-02 6 views
13

Mi chiedevo se fosse possibile eseguire una composizione funzionale con funzioni che richiedessero più di un argomento. Voglio essere in grado di fare qualcosa di simileComposizione funzionale con funzioni multivalore in haskell?

x = (+3).(*) 

x impostazione pari a una funzione che aggiunge tre per il prodotto di due numeri.

+4

http://conal.net/blog/posts/semantic-editor-combinators – luqui

+1

[This] (http://stackoverflow.com/questions/9656797/variadic-compose-function) potrebbe essere quello che stai cercando . – is7s

risposta

23

Ci sono diversi modi per farlo, ma sono tutti un po 'imbarazzante.

((+3).) . (*) 
≡ fmap (+3) . (*) 
≡ curry $ (+3) . uncurry (*) 
≡ \l r -> l*r + 3 

Oh, aspetta, questa è stata la firma, dove c'è anche una definizione compatta, indovinate come si chiama ...

((.).(.)) (+3) (*) 

Direi che la soluzione lambda, essendo più esplicita, è piuttosto il migliore qui.

cosa aiuta, ed è spesso fatto solo a livello locale come -liner uno (o due), è quello di definire questa composizione come un infisso personalizzato:

(.:) :: (c->d) -> (a->b->c) -> a->b->d 
f .: i = \l r -> f $ i l r 

che permette di scrivere semplicemente (+3) .: (*).

proposito, per la simile (b->b->c) -> (a->b) -> a->a->c (precomponete la funzione diritto di entrambi argomenti della infisso) esiste a widely-used standard implementation.

+1

'Mi piace ((.). (.))' Il migliore, soprattutto perché mi piace immaginare [Frankie Howerd] (http://en.m.wikipedia.org/wiki/Frankie_Howerd) scoperto –

+0

+1 per fmap (il più bello) e il lambda (quello che vorrei in qualsiasi base di codice su cui stavo lavorando!) – monk

+0

sì - prendi il lambda o meglio dai un nome alla funzione - in tutta onestà: le altre soluzioni sono piacevoli intellettuali ma più o meno illeggibile (è possibile li riscoprire facilmente vero, ma direi illeggibile) - cose come questo dà Haskell è etichetta "arcane ebano-tower" che scoraggia tanti buoni sviluppatori di guardare in Haskell – Carsten

2

si potrebbe anche utilizzare la B1 o combinatore merlo da Data.Aviary.Birds. Penso che per il lavoro vero utilizzerei comunque un lambda.