Простой вопрос: почему это не вызывает правило перезаписи?
{-# RULES "fmap/fmap" forall f g xs. fmap f (fmap g xs) = fmap (f.g) xs #-}
main = do
txt <- fmap head (fmap words (readFile "foo.txt"))
print txt
Теперь я хотел написать, что извлечение fun
запускает правило, потому что это было в предыдущем тесте... не в этот раз.
{-# RULES "fmap/fmap" forall f g xs. fmap f (fmap g xs) = fmap (f.g) xs #-}
fun f g xs = fmap f (fmap g xs)
main = do
txt <- fun (drop 1) words (readFile "foo.txt")
print txt
До тех пор, пока я случайно не добавлю имя модуля:
module Main where
{-# RULES "fmap/fmap" forall f g xs. fmap f (fmap g xs) = fmap (f.g) xs #-}
fun f g xs = fmap f (fmap g xs)
main = do
txt <- fun head words (readFile "foo.txt")
print txt
Теперь он все еще не работает, если я просто напишу приложение функции в основной функции.
Подводя итог:
-
txt <- fmap head (fmap words (readFile "foo"))
не работает -
txt <- fun head words (readFile "foo")
не работает -
txt <- fun head words (readFile "foo")
plus работает модуль -
fun f g xs = fmap f . fmap g $ xs
plus модуль не работает -
fun f g xs = f <$> (g <$> xs)
плюс модуль работает (но срабатывает позже)
Все это было сделано, вызвав ghc --make -O2 -ddump-rule-firings Main.hs
. Пример вывода:
# ghc --make -O2 -ddump-rule-firings Main.hs
[1 of 1] Compiling Main ( Main.hs, Main.o )
Rule fired: fmap/fmap
Rule fired: unpack
Rule fired: Class op >>=
Rule fired: Class op fmap
Rule fired: Class op fmap
Rule fired: Class op show
Rule fired: Class op showList
Rule fired: unpack-list
Linking Main ...