Я включаю свои представления из моих контроллеров. Я также определяю расположение файлов, чтобы упростить обслуживание.
config.php
define('DIR_BASE', dirname( dirname( __FILE__ ) ) . '/');
define('DIR_SYSTEM', DIR_BASE . 'system/');
define('DIR_VIEWS', DIR_SYSTEM . 'views/');
define('DIR_CTLS', DIR_SYSTEM . 'ctls/');
define('DIR_MDLS', DIR_SYSTEM . 'mdls/');
define('VIEW_HEADER', DIR_VIEWS . 'header.php');
define('VIEW_NAVIGATION', DIR_VIEWS . 'navigation.php');
define('VIEW_FOOTER', DIR_VIEWS . 'footer.php');
Теперь у меня есть вся информация, которую мне нужно, просто включив config.php
.
controller.php
require( '../config.php' );
include( DIR_MDLS . 'model.php' );
$model = new model();
if ( $model->getStuff() ) {
$page_to_load = DIR_VIEWS . 'page.php';
}
else {
$page_to_load = DIR_VIEWS . 'otherpage.php';
}
include( VIEW_HEADER );
include( VIEW_NAVIGATION );
include( DIR_VIEWS . $page_to_load );
include( VIEW_FOOTER );
Рекурсия для foldr f x ys
, где ys = [y1,y2,...,yk]
похож
f y1 (f y2 (... (f yk x) ...))
, тогда как рекурсия для foldl f x ys
похожа
f (... (f (f x y1) y2) ...) yk
важное различие здесь, то, что, если результат f x y
может быть вычислен с помощью только значение x
, то foldr
не должен' исследовать весь список. Например
foldr (&&) False (repeat False)
возвраты False
, тогда как
foldl (&&) False (repeat False)
никогда не завершается. (Отметьте: repeat False
создает бесконечный список, где каждый элемент False
.)
, С другой стороны, foldl'
хвост, рекурсивный и строгий. Если Вы знаете, что необходимо будет пересечь целый список, неважно, что (например, суммируя числа в списке), то foldl'
больше пространства - (и вероятно время-) эффективный, чем [1 115].
Причина foldl'
предпочтена foldl
для 99% всего использования, то, что это может работать в постоянном пространстве за большей частью использования.
Берут функцию sum = foldl['] (+) 0
. Когда foldl'
используется, сумма сразу вычисляется, таким образом применение sum
к бесконечному списку будет просто работать навсегда, и скорее всего в постоянном пространстве (если you’re с помощью вещей как Int
с, Double
с, Float
с. Integer
с будет использовать больше, чем постоянное пространство, если число станет больше, чем maxBound :: Int
).
С [1 110], преобразователь создается (как рецепт того, как получить ответ, который может быть оценен позже, вместо того, чтобы хранить ответ). Эти преобразователи могут поднять много пространства, и в этом случае, it’s намного лучше для оценки выражения, чем сохранить преобразователя (ведущий к стеку overflow… и продвижение Вас to… о, не берите в голову)
Hope, которая помогает.
Их семантика отличается так, Вы не можете просто чередоваться foldl
и foldr
. Тот складывает элементы слева, другой справа. Тем путем оператор применяется в различном порядке. Это имеет значение для всех неассоциативных операций, таких как вычитание.
Haskell.org имеет интересное статья о предмете.
Вскоре, foldr
лучше, когда функция аккумулятора ленива на своем втором аргументе. Считайте больше в Haskell Wiki Переполнение стека (предназначенная игра слов).
Между прочим, Ruby inject
и Clojure reduce
составляют foldl
(или foldl1
, в зависимости от на какой версии вы используете). Обычно, когда в языке есть только одна форма, это левая складка, включая Python reduce
, Perl List :: Util :: reduce
, C ++ create
], C # Aggregate
, Smalltalk inject: into:
, PHP array_reduce
, Mathematica Fold
и т. Д. Common Lisp's reduce 1145246] по умолчанию используется левое сгибание, но есть возможность правого сгиба.
Как указывает Конрад , их семантика различна. У них даже нет одного и того же типа:
ghci> :t foldr
foldr :: (a -> b -> b) -> b -> [a] -> b
ghci> :t foldl
foldl :: (a -> b -> a) -> a -> [b] -> a
ghci>
Например, оператор добавления списка (++) может быть реализован с помощью foldr
as
(++) = flip (foldr (:))
, а
(++) = flip (foldl (:))
выдаст ошибку типа.