Пример строгой оценки из книги Саймона Марлоу «Параллельное и параллельное программирование в 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для подробностей. Он делает много пробуксовки через узоры взрыва и тому подобное.

Другие вопросы по тегам