В реализации многих функций на платформе haskell есть очень распространенный шаблон, который меня беспокоит, но я не смог найти объяснения. Речь идет об использовании вложенных функций для оптимизации.
Причина вложенных функций в предложениях where, когда они нацелены на хвостовую рекурсию, мне очень ясна (как в length), но в чем смысл, когда внутренняя функция имеет точно такой же тип, что и функция верхнего уровня? Это происходит, например, во многих функциях Data.Set модуль, как показано ниже:
-- | /O(log n)/. Is the element in the set?
member :: Ord a => a -> Set a -> Bool
member = go
where
STRICT_1_OF_2(go)
go _ Tip = False
go x (Bin _ y l r) = case compare x y of
LT -> go x l
GT -> go x r
EQ -> True
#if __GLASGOW_HASKELL__ >= 700
{-# INLINABLE member #-}
#else
{-# INLINE member #-}
#endif
Я подозреваю, что это может иметь какое-то отношение к запоминанию, но я не уверен.
изменить: поскольку dave4420 предлагает строгость, вот определение макроса STRICT_1_OF_2, которое можно найти в том же модуле:
-- Use macros to define strictness of functions.
-- STRICT_x_OF_y denotes an y-ary function strict in the x-th parameter.
-- We do not use BangPatterns, because they are not in any standard and we
-- want the compilers to be compiled by as many compilers as possible.
#define STRICT_1_OF_2(fn) fn arg _ | arg `seq` False = undefined
Я понимаю, как работает этот макрос, однако я все еще не понимаю, почему go вместе с STRICT_1_OF_2(go) нельзя перемещать на верхний уровень вместо member.
Может, это не из-за оптимизации, а просто из-за стилистического выбора?
редактировать 2: я добавил части INLINABLE и INLINE из модуля set. Не думал, что они могут иметь к этому какое-то отношение на первый взгляд.
memberдолжен быть оценен, но первый аргументgoвсегда уже будет оценен. Но я не уверен. - person dave4420   schedule 18.03.2012xбыть свободным вgo. Мне не нравится стиль, в котором это написано, так как это, кажется, подразумевает, что x получает seq:ed в каждой итерации. Кроме того, он делает членов строгими вx, когда это не обязательно (но это второстепенно). - person augustss   schedule 18.03.2012