Bu ekleme operatör için gerekli değildir, ancak genel olarak argümanları çevirir nihai denklemi ekleyerek tüm çevrilmiş davaları uygulamadan bir işlev değişmeli yapabilirsiniz:
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
Ancak, olumsuz olmasıdır Eğer bir durumun ele alınması unutursanız, bu kolayca sonsuz bir döngüye yol açar:
İşte
adjacent A B = True
adjacent B C = True
adjacent x y = adjacent y x
, adjacent A C
vb adjacent A C
arama ve hangi, adjacent C A
çağırır. Ve GHC’nin desen eşleme kontrolü (-fwarn-incomplete-patterns
veya -Wall
) burada size yardımcı olmaz.
Sana döngü önlemek için ek bir bağımsız değişken sanırım: Eğer çevirdi ama hiçbir maç oldu hala durumun ele alınması go Reverse
denklem eklemek yoksa
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
Şimdi GHC şikayet edecektir.
Ancak, bunun yalnızca çok sayıda durumda olan işlevler için uygun olduğunu düşünüyorum. Aksi takdirde, hepsini sıralamak daha nettir.
Normal olarak eklemeyi tanımlayabilir ve ücretsiz olarak (yavaş) değişebilirlik elde edebilirsiniz. – ThreeFx
Ayrıca, bu zaten bir yanıt var [burada] (http://stackoverflow.com/questions/29210248/haskell-defining-commutative-functions-how-to-consider-actual-arguments-by-co). (Kullanım durumunuzdan daha geneldir, bu nedenle muhtemelen önerilen paketi nasıl kullanacağınız konusunda biraz araştırma yapmanız gerekir) – ThreeFx
Eğer tembelliği hesaba katarsanız hemen hemen hiçbir işlem tamamen değişkendir, çünkü tipik olarak 'f tanımsız x 'farklı olabilir. fx undefined ', desen eşleştirmesinin aslında ardışık olması nedeniyle. İşlevsel dillerin işlevsel ve anlamsal semantiği arasında tam bir soyutlama elde etmenin bu kadar zor olmasının nedeni budur: anlamsal anlamlarda, aslında dilde tanımlanamayan paralel ya da benzeri işlevleri içerir. – Bakuriu