Non è necessario che questo operatore addizione, ma in generale si può effettuare una funzione commutativa senza implementare tutti i casi capovolte aggiungendo un'equazione finale che lancia gli argomenti:
data X = A | B | C
adjacent A B = True
adjacent B C = True
adjacent A C = False
adjacent x y = adjacent y x -- covers B A, C B, and C A
Tuttavia, lo svantaggio è che se si dimentica per trattare un caso, questo porta facilmente ad un ciclo infinito:
adjacent A B = True
adjacent B C = True
adjacent x y = adjacent y x
Qui, adjacent A C
chiamerebbe adjacent C A
, che avrebbe chiamato adjacent A C
, e così via. E il modello di GHC corrisponde al controllo di esaustività (-fwarn-incomplete-patterns
o -Wall
) non ti aiuterà qui.
Credo che si potrebbe aggiungere un ulteriore argomento per prevenire loop:
data Commute = Forward | Reverse
adjacent = go Forward
where
go _ A B = True
go _ B C = True
go Forward x y = go Reverse y x -- try to commute
go Reverse _ _ = False -- commuting failed
Ora GHC si lamenterà se non si aggiunge l'equazione go Reverse
per gestire il caso in cui si ha commutato ma c'era ancora alcuna corrispondenza.
Ma penso che questo sia adatto solo per le funzioni con un numero elevato di casi, altrimenti è molto più semplice enumerarli tutti.
fonte
2016-05-19 22:13:37
È possibile definire l'aggiunta normalmente e ottenere la commutatività (lenta) gratuitamente. – ThreeFx
Inoltre, questo ha già una risposta [qui] (http://stackoverflow.com/questions/29210248/haskell-defining-commutative-functions-how-to-consider-actual-arguments-by-co). (È più generico del tuo caso d'uso, quindi probabilmente devi fare qualche ricerca su come utilizzare il pacchetto suggerito) – ThreeFx
Se si considera la pigrizia quasi nessuna operazione è completamente commutativa perché tipicamente 'f undefined x' può essere differente da' fx undefined' a causa del fatto che la corrispondenza del modello è essenzialmente sequenziale. Questo è il motivo per cui è così difficile ottenere la piena astrazione tra semantica operativa e denotativa dei linguaggi funzionali: nella semantica denotativa si includono funzioni come parallele o ecc. Che non possono essere effettivamente definite nella lingua. – Bakuriu