Пример строгой оценки из книги Саймона Марлоу «Параллельное и параллельное программирование в Haskell»
Саймон Марлоу в своей книге «Параллельное и параллельное программирование в Haskell» пишет:
Операция вставки имела эту строку:
putMVar m (Map.insert name number book)
Это помещает в MVar неоцененное выражение
Map.insert name number book
. Если бы мы выполняли несколько операций вставки подряд, MVar выстраивал бы большую цепочку неоцененных выражений. Чтобы получить кратковременную блокировку и отсутствие утечки места, нам нужно использовать трюк:let book' = Map.insert name number book putMVar m book' seq book' (return ())
С помощью этой последовательности мы сохраняем неоцененное выражение в MVar, но оно вычисляется сразу после putMVar.
Я не понимаю.
seq a b
операция оценивает
a
при слабой голове нормальная форма. Так будет неоцененное выражение. Как я вижу, оценивается только конструктор карты, и все его содержимое не оценивается.
2 ответа
Как я вижу, оценивается только конструктор, а все его содержимое не оценивается.
Внутри
Map
Тип реализован с использованием строгого дерева. Либо оценивается весь корешок дерева, либо ничего. Вот фрагмент кода библиотеки:
data Map k a = Bin {-# UNPACK #-} !Size !k a !(Map k a) !(Map k a)
| Tip
Аннотации строгости (
!
) предотвращают сохранение неоцененных значений в виде поддеревьев. Итак, если мы оценим
Map k a
значение слабой головы нормальной формы, мы фактически полностью оцениваем корешок дерева.
Map
в
Map.insert
не является конструктором карты. Это имя модуля. Функцияinsert :: Ord k => k -> a -> Map k a -> Map k a
называется здесь. Его результат будет оценен как WHNF перед
return ()
вычисляется как следующий вычислительный шаг в комбинированном действии ввода-вывода благодаря вызову
seq
. Вы можете проконсультироваться с источником
insert
для подробностей. Он делает много пробуксовки через узоры взрыва и тому подобное.