{-# LANGUAGE CPP #-} #if __GLASGOW_HASKELL__ >= 704 {-# LANGUAGE Safe #-} #endif ----------------------------------------------------------------------------- -- | -- Module : Data.NF -- Copyright : (c) Stanford University 2015 -- License : BSD-style (see the file LICENSE) -- -- Maintainer : ezyang@cs.stanford.edu -- Stability : experimental -- Portability : portable -- -- This module provides a data type, 'NF', representing data which has -- been evaluated to \"Normal Form\". This is a useful type discipline -- for many situations when normal form data is necessary, e.g. when -- transmitting data to other threads over channels. If a library -- that you are using has the following type: -- -- @ -- strictWriteChan :: 'NFData' a => 'Control.Concurrent.Chan' a -> a -> 'IO' () -- @ -- -- you can specialize it to the following type in order to avoid the -- cost of repeatedly 'deepseq'ing a value when it is not necessary: -- -- @ -- strictWriteChan_ :: 'Control.Concurrent.Chan' ('NF' a) -> 'NF' a -> 'IO' () -- strictWriteChan_ = strictWriteChan -- @ -- -- You should also consider providing APIs which only accept 'NF' -- values, to prevent users from accidentally 'deepseq'ing. module Data.NF ( NF, makeNF, getNF, ) where import Control.DeepSeq import Data.NF.Internal -- | Creates a value of type 'NF'. The first time the result is -- evaluated to whnf, the value will be 'rnf'ed. To avoid this -- 'rnf', see 'UnsafeNF'. makeNF :: NFData a => a -> NF a makeNF x = x `deepseq` UnsafeNF x -- | Retrieves @a@ from a value of type @'NF' a@; this value -- is guaranteed to be in normal form. getNF :: NF a -> a getNF (UnsafeNF a) = a