O ile wiem, nie sądzę, że mogłoby to spowodować jakąkolwiek różnicę, że id1 i id2 pochodzą z klasy typów, a id1 i id2 nie. Używam "ghc Rewrite" z najnowszą platformą Haskell (zarówno w wersji GHC 7.0.4, jak i teraz w wersji 7.4.1), i spodziewam się, że to1 również wystrzeli.Reguły przepisywania niepoprawne w przypadku reguł pasujących do wielu metod instancji
$ ghc Rewrite
[1 of 1] Compiling RewriteProblems (Rewrite.hs, Rewrite.o)
Rule fired: rewrite/ez'
Rule fired: rewrite/to1'
Rule fired: rewrite/ez
Rule fired: rewrite/ez
Rule fired: Class op id2
Rule fired: Class op id2
przykład:
{-# OPTIONS_GHC -O -ddump-rule-firings #-}
module RewriteProblems where
{-# RULES
"rewrite/ez" forall a. id1 a = RDUnit
"rewrite/to1" forall a. id2 (id2 a) = id1 a
"rewrite/ez'" forall a. id1' a = RDUnit
"rewrite/to1'" forall a. id2' (id2' a) = id1 a
#-}
class Ider a where
id1 :: a -> a
id2 :: a -> a
data RewriteD = RDUnit
instance Ider RewriteD where
{-# INLINE[1] id1 #-}
{-# INLINE[1] id2 #-}
id1 a = RDUnit
id2 a = RDUnit
testThing1 :: RewriteD
testThing1 = id1 RDUnit
testThing2 :: RewriteD
testThing2 = id2 (id2 RDUnit)
testThing1' :: RewriteD
testThing1' = id1' RDUnit
testThing2' :: RewriteD
testThing2' = id2' (id2' RDUnit)
{-# INLINE[1] id1' #-}
{-# INLINE[1] id2' #-}
id1' :: RewriteD -> RewriteD
id2' :: RewriteD -> RewriteD
id1' a = RDUnit
id2' a = RDUnit
Właśnie zainstalowałem najnowszą wersję GHC - w wersji 7.4.1 i otrzymuję to samo teraz, co poprzednio. Również, tak, zdaję sobie sprawę, że te zasady nie mają znaczenia dla wyników - właśnie zrobiłem ten test, aby wyizolować problem, który dostałem w znacznie bardziej skomplikowanym przykładzie. Wierzę również, że pierwszeństwo właściwie działa tutaj ... po prostu patrząc na wynik naprawdę wygląda na to, że wszystkie moje reguły są podejmowane zanim pojawią się te. – Akh
Jak dokładnie określasz, że twoje reguły są podejmowane? Nie wiem, w jaki sposób GHC może pokazywać reguły, które nie są stosowane, lub która reguła jest używana w przypadku wielu dopasowań. Najlepsze, co możesz zrobić, to sprawdzić, co faktycznie zostało wyrzucone, co jest w tym przypadku regułą klasy op. –
Jeśli zmienisz program, aby metoda instancji zwróciła coś podobnego do błędu, czyli coś innego niż 'RDUnit', na które powinna Cię opuścić reguła przepisywania, optymalizator pozostawia ci wartość błędu w przykładzie' testThing2'. Myślę, że ten przykładowy program był po prostu zbyt daleko posunięty, aby jak najbardziej jasno pokazać problem. – Anthony