Control.DeepSeq
| Авторские права | (c) Университет Глазго 2001-2009 |
|---|---|
| Лицензия | BSD-стиль (см. файл LICENSE) |
| Поддержка | libraries@haskell.org |
| Стабильность | стабильно |
| Переносимость | переносимо |
| Safe Haskell | Безопасно |
| Язык | Haskell2010 |
Описание
Этот модуль предоставляет перегруженную функцию, deepseq, для полной оценки структур данных (то есть, оценки до «Нормальной формы»).
Типичное применение — предотвращение утечек ресурсов в ленивых программах ввода-вывода, принудительно читая все символы из файла. Например:
import System.IO
import Control.DeepSeq
main = do
h <- openFile "f" ReadMode
s <- hGetContents h
s `deepseq` hClose h
return s
deepseq отличается от seq, так как рекурсивно проходит по структурам данных, например, seq будет оценивать только до первого конструктора в списке:
> [1,2,undefined] `seq` 3 3
В то время как deepseq заставит оценить все элементы списка:
> [1,2,undefined] `deepseq` 3 *** Exception: Prelude.undefined
Другое распространенное применение — гарантировать, что любые исключения, скрытые в ленивых полях структуры данных, не утекут за пределы обработчика исключений, или принудительно оценить структуру данных в одном потоке перед передачей другому потоку (чтобы предотвратить перемещение работы в неправильные потоки).
С версии: 1.1.0.0
deepseq :: NFData a => a -> b -> b Источник
deepseq: полностью оценивает первый аргумент, прежде чем вернуть второй.
Имя deepseq используется для иллюстрации связи с seq: где seq является поверхностной в том смысле, что она оценивает только верхний уровень своего аргумента, deepseq проходит по всей структуре данных, полностью её оценивая.
deepseq может быть полезным для принудительной обработки ожидаемых исключений, устранения утечек памяти или принудительного выполнения ленивых операций ввода-вывода. Также полезно в сочетании с параллельными стратегиями (см. пакет parallel).
Гарантии о порядке оценки нет. Реализация может оценивать компоненты структуры в любом порядке или параллельно. Чтобы наложить фактический порядок на оценку, используйте pseq из Control.Parallel в пакете parallel.
С версии: 1.1.0.0
($!!) :: NFData a => (a -> b) -> a -> b infixr 0 Источник
глубокий аналог $!. В выражении f $!! x, x полностью оценивается перед применением функции f к нему.
С версии: 1.2.0.0
force :: NFData a => a -> a Источник
вариант deepseq, который полезен в некоторых случаях:
force x = x `deepseq` x
force x полностью оценивает x, а затем возвращает его. Обратите внимание, что force x выполняет оценку только при запросе значения force x самого по себе, поэтому по существу превращает поверхностную оценку в глубокую.
force удобно использовать в сочетании с ViewPatterns.
{-# LANGUAGE BangPatterns, ViewPatterns #-}
import Control.DeepSeq
someFun :: ComplexData -> SomeResult
someFun (force -> !arg) = {- 'arg' will be fully evaluated -}
Другое полезное применение — объединить force с evaluate для принудительной глубокой оценки по отношению к другим операциям IO.
import Control.Exception (evaluate)
import Control.DeepSeq
main = do
result <- evaluate $ force $ pureComputation
{- 'result' will be fully evaluated at this point -}
return ()
С версии: 1.2.0.0
Класс типов, которые можно полностью оценить.
С версии: 1.1.0.0
Минимальное полное определение
Ничего
Методы
rnf должен привести свой аргумент к нормальной форме (то есть, полностью оценить все подкомпоненты), а затем вернуть '()'.
Generic NFData производные
Начиная с GHC 7.2, вы можете автоматически выводить экземпляры для типов, имеющих экземпляр Generic.
{-# LANGUAGE DeriveGeneric #-}
import GHC.Generics (Generic)
import Control.DeepSeq
data Foo a = Foo a String
deriving (Eq, Generic)
instance NFData a => NFData (Foo a)
data Colour = Red | Green | Blue
deriving Generic
instance NFData Colour
Начиная с GHC 7.10, пример выше можно записать более лаконично, включив новую расширение DeriveAnyClass:
{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
import GHC.Generics (Generic)
import Control.DeepSeq
data Foo a = Foo a String
deriving (Eq, Generic, NFData)
data Colour = Red | Green | Blue
deriving (Generic, NFData)
Совместимость с предыдущими версиями deepseq
До версии 1.4.0.0, реализация по умолчанию метода rnf была определена как
rnfa =seqa ()
Однако, начиная с deepseq-1.4.0.0, реализация по умолчанию основана на DefaultSignatures, что позволяет получать более точные автоматически выводимые экземпляры NFData. Если вам нужны семантика реализации метода rnf по умолчанию, которая использовалась ранее, используйте
instance NFData Colour where rnf x = seq x ()
или альтернативно
{-# LANGUAGE BangPatterns #-}
instance NFData Colour where rnf !_ = ()
Экземпляры
| NFData Bool | |
| NFData Char | |
| NFData Double | |
| NFData Float | |
| NFData Int | |
| NFData Int8 | |
| NFData Int16 | |
| NFData Int32 | |
| NFData Int64 | |
| NFData Integer | |
| NFData Word | |
| NFData Word8 | |
| NFData Word16 | |
| NFData Word32 | |
| NFData Word64 | |
| NFData TypeRep |
ПРИМЕЧАНИЕ: Определено только для С версии: 1.4.0.0 |
| NFData () | |
| NFData Void |
С версии: 1.4.0.0 |
| NFData Unique | С версии: 1.4.0.0 |
| NFData Natural | С версии: 1.4.0.0 |
| NFData Version | С версии: 1.3.0.0 |
| NFData ThreadId | С версии: 1.4.0.0 |
| NFData CChar | С версии: 1.4.0.0 |
| NFData CSChar | С версии: 1.4.0.0 |
| NFData CUChar | С версии: 1.4.0.0 |
| NFData CShort | С версии: 1.4.0.0 |
| NFData CUShort | С версии: 1.4.0.0 |
| NFData CInt | С версии: 1.4.0.0 |
| NFData CUInt | С версии: 1.4.0.0 |
| NFData CLong | С версии: 1.4.0.0 |
| NFData CULong | С версии: 1.4.0.0 |
| NFData CLLong | С версии: 1.4.0.0 |
| NFData CULLong | С версии: 1.4.0.0 |
| NFData CFloat | С версии: 1.4.0.0 |
| NFData CDouble | С версии: 1.4.0.0 |
| NFData CPtrdiff | С версии: 1.4.0.0 |
| NFData CSize | С версии: 1.4.0.0 |
| NFData CWchar | С версии: 1.4.0.0 |
| NFData CSigAtomic | С версии: 1.4.0.0 |
| NFData CClock | С версии: 1.4.0.0 |
| NFData CTime | С версии: 1.4.0.0 |
| NFData CUSeconds | С версии: 1.4.0.0 |
| NFData CSUSeconds | С версии: 1.4.0.0 |
| NFData CFile | С версии: 1.4.0.0 |
| NFData CFpos | С версии: 1.4.0.0 |
| NFData CJmpBuf | С версии: 1.4.0.0 |
| NFData CIntPtr | С версии: 1.4.0.0 |
| NFData CUIntPtr | С версии: 1.4.0.0 |
| NFData CIntMax | С версии: 1.4.0.0 |
| NFData CUIntMax | С версии: 1.4.0.0 |
| NFData All | С версии: 1.4.0.0 |
| NFData Any | С версии: 1.4.0.0 |
| NFData TyCon |
ПРИМЕЧАНИЕ: Определено только для С версии: 1.4.0.0 |
| NFData Fingerprint | С версии: 1.4.0.0 |
| NFData a => NFData [a] |
| (Integral a, NFData a) => NFData (Ratio a) | |
| NFData (StableName a) | С момента: 1.4.0.0 |
| NFData a => NFData (Identity a) | С момента: 1.4.0.0 |
| NFData (Fixed a) | С момента: 1.3.0.0 |
| NFData a => NFData (Complex a) | |
| NFData a => NFData (ZipList a) | С момента: 1.4.0.0 |
| NFData a => NFData (Dual a) | С момента: 1.4.0.0 |
| NFData a => NFData (Sum a) | С момента: 1.4.0.0 |
| NFData a => NFData (Product a) | С момента: 1.4.0.0 |
| NFData a => NFData (First a) | С момента: 1.4.0.0 |
| NFData a => NFData (Last a) | С момента: 1.4.0.0 |
| NFData a => NFData (Down a) | С момента: 1.4.0.0 |
| NFData a => NFData (Maybe a) | |
| NFData (a -> b) |
Этот экземпляр предназначен для удобства и согласованности с С момента: 1.3.0.0 |
| (NFData a, NFData b) => NFData (Either a b) | |
| (NFData a, NFData b) => NFData (a, b) | |
| (Ix a, NFData a, NFData b) => NFData (Array a b) | |
| NFData a => NFData (Const a b) | С момента: 1.4.0.0 |
| NFData (Proxy * a) | С момента: 1.4.0.0 |
| (NFData a, NFData b, NFData c) => NFData (a, b, c) | |
| (NFData a, NFData b, NFData c, NFData d) => NFData (a, b, c, d) | |
| (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5) => NFData (a1, a2, a3, a4, a5) | |
© The University of Glasgow and others
Licensed under a BSD-style license (see top of the page).
https://downloads.haskell.org/~ghc/7.10.3/docs/html/libraries/deepseq-1.4.1.1/Control-DeepSeq.html