2012-02-08 6 views
6

Предположим, у меня есть две функции: f :: [a] -> b и g :: [a] -> c. У меня есть следующие два вопроса:Возможно ли, чтобы представленный случай был оптимизирован в один цикл?

  1. Если я выполняю (f &&& g) xs где xs :: [a], и если оба f и g включают петли, возможно ли компилятор оптимизировать эти две петли в одну? (Обратите внимание, что я не спрашиваю, реализует ли некоторый конкретное Haskell компилятор это. Я хочу знать, является ли такой вещь возможно.)

  2. Может traverse функции из класса помощи Traverse типа меня есть такая оптимизация с что-то по следующим направлениям:

    traverse (someCombinator f g) xs 
    
+0

Я думаю, что оптимизация, как в 1., может выполняться суперкомпиляторами. – Landei

ответ

9

теоретически можно оптимизировать этот код, но очень и очень трудно, потому что f и g может потреблять различные количества входного списка. Только когда они потребляют ту же сумму, или g всегда потребляет больше списка, чем f (или наоборот), можно ли было бы оптимизировать. Проблема с остановкой предотвращает компилятор от обнаружения таких условий в сложном коде.

Только в простых случаях, когда как f, так и g использовать, например, можно было бы, например, выполнить тривиальные оптимизации без дальнейшей интроспекции.

traverse функция не поможет здесь, потому что не существует разумный способ реализации someCombinator (Как вы хотите, чтобы преобразовать несколько вызовов a-й в один [a] без серьезных взломов? А потом вы туда, где вы начали в любом случае).

Ваш единственный реальный вариант, чтобы сделать f и g в папки, так что у них есть подписи f :: a -> b -> b и g :: a -> c -> c, а это означает, что значение b и c может быть вычислена с приращением. Затем вы можете использовать \ a -> f a *** g a, чтобы получить папку, которую вы можете использовать в обычном (в данном случае) сбрасывании.

+0

Отличный ответ. Большое спасибо! Я разместил этот вопрос, потому что я хотел проверить, что я сказал в этой статье (http://stackoverflow.com/questions/9162256/cartesian-product-traverse-in-scalaz/9162706#9162706) (как в ответном, так и в в комментариях) была правильной. – missingfaktor