2012-07-19 16 views
7

Quindi continuo a sentire molto sulla programmazione senza punti e ho deciso di fare un piccolo esperimento per testare la mia comprensione. Ciò comportava l'assunzione di una funzione appuntita per calcolare il fattoriale di un numero e convertirlo in una forma senza punti. Sono riuscito a farlo, ma il risultato point free è molto meno leggibile del risultato a punta.Notazione senza punto, ricorsione e corrispondenza di modelli

-- pointed 
fact 0 = 1 
fact n = n * (fact (n-1)) 
-- point free 
fact' = foldr1 (*) . takeWhile ((<) 0) . iterate (flip (-) 1) 

mi sto perdendo qualcosa di essenziale per puntare la notazione libero o è questo come leggibile come certe trasformazioni ottenere? Per me sembra che una grande parte della funzione fact sia la corrispondenza del modello su zero, e infatti, la corrispondenza dei pattern è uno dei motivi principali per cui amo Haskell. Tuttavia la notazione punto-punto sembra completamente non consentire ciò, insieme ad alcune altre cose che sono estremamente utili come la comprensione delle liste.

+6

preferisco 'prodotto. enumFromTo 1'. – Vitus

+5

[Evoluzione di un programmatore Haskell] (http://www.willamette.edu/~fruehr/haskell/evolution.html) – sdcvvc

+2

Attendere. Ti aspettavi _readability_ dalla sintassi _point-free_? Ha. Haha. Ha ha ha ha ha. No. –

risposta

15

Il fattoriale canonica in forma pointfree è:

fact = product . enumFromTo 1 

(che equivale a fact n = product [1..n])

Trovo che questo sia abbastanza leggibile. Tuttavia, concordo che la versione originale:

fact 0 = 1 
fact n = n * (fact (n-1)) 

Corrisponde alla definizione molto bene ed è anche leggibile.

Il punto (ha!) Di forma senza punti è per rendere più facile ragionare su funzioni come la composizione di altre funzioni. Tuttavia, la funzione fattoriale non è davvero un candidato eccellente per questo tipo di ragionamento.

La decisione è tua, ovviamente.

+0

Interessante, non sapevo che esistesse una funzione come enumFromTo. Quindi per quanto riguarda la corrispondenza dei modelli? Per necessità che richiede notazione puntata. Vorresti sostenere che ciò non rientra nei limiti del ragionamento sulle funzioni come composizione? – Dwilson

+0

@Dwilson: fa parte della classe di caratteri 'Enum': http: //hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html # t: Enum –

+3

@Dwilson: puoi tradurre la corrispondenza del modello in notazione point-free. Basta dare un'occhiata a funzioni come 'maybe' o' either'; prendendo '' o' come esempio: gli dai due funzioni, una per 'Left' e la seconda per il caso' Right' e il gioco è fatto. In effetti, puoi facilmente costruire queste funzioni perché fanno parte dell'isomorfismo tra l'ADT e la sua codifica della Chiesa. Le liste probabilmente non hanno tale funzione, ma è facile da implementare: 'listcase [] z f = z; listcase (x: xs) z f = f x xs'. – Vitus

2

Per ogni tipo di dati di unione algebrica deve esistere la sua funzione discriminatore tra maiuscole e minuscole che incapsula la corrispondenza del modello per quel tipo. Abbiamo già

either :: (a -> c) -> (b -> c) -> Either a b -> c 
maybe :: b -> (a -> b) -> Maybe a -> b 

Allo stesso modo ci deve essere tale funzione per i numeri,

num :: (Num a) => b -> (a -> b) -> a -> b 
num z nz 0 = z 
num z nz x = nz x 

così possiamo scrivere

import Control.Applicative 
import Data.Function 

fact :: (Num a) => a -> a 
fact x = num 1 (\x-> (*) (fact (pred x)) x) x 
     = num 1 ((*) =<< (fact.pred)) x 

cioè

fact = (num 1 . ((*) =<<) . (. pred)) fact 
     = fix (num 1 . ((*) =<<) . (. pred)) 
+1

Heck, ora è _molto_ più leggibile di 'prodotto. enumFromTo 1' ... – leftaroundabout

+1

@leftaroundabout c'era un ':)' qualche parte forse? .... :) il punto principale che volevo fare era in realtà con la funzione 'num'. ma anche, per rispondere al titolo più da vicino - non si tratta del 'fattoriale' di per sé ... –

+0

Mentre certamente meno leggibile, questo è interessante. Potresti approfondire un po 'di più la prima frase e cosa significa 'num' in relazione a ciò, in particolare la parte relativa alla funzione discriminatore del caso tipo? – Dwilson

Problemi correlati