每次调用函数时生成唯一值?

时间:2019-04-09 21:48:02

标签: haskell

我如何制作一个Haskell函数,该函数每次在程序过程中被调用时都会生成一个唯一值?

一个想法是:

incrementInteger :: IO (Integer)
incrementInteger = -- ...

使得它每次在程序过程中被调用时都递增(无论从哪个线程调用,等等)。

incrementIngeter
=> 0

incrementInteger
=> 1

incrementInteger
=> 2

也就是说,我对此函数唯一关心的属性是“无论如何,每次调用该值都是唯一的”。该怎么做?

编辑:看来Data.UUID是通过generatedNamed提供的。

2 个答案:

答案 0 :(得分:7)

base软件包为此提供了newUnique。 (注:这些值在单个程序运行中将是唯一的,但不一定跨运行。)

答案 1 :(得分:5)

我可能首先会使用State Integer来解决此问题,或者如果代码已经在IO中,然后为ReaderT (IORef Integer) IO编写包装,则可能会解决。与全局计数器相比,更易于理解的代码可以明确指出哪些函数可以访问和修改值。

但是,如果所有其他方法都失败了,并且您确实希望它是程序全局的,那么在GHC Haskell中通常使用的不安全方法是:

import Data.IORef
import System.IO.Unsafe (unsafePerformIO)

-- A global mutable counter
-- The NOINLINE is critical to ensure the counter is unique
counter :: IORef Integer
counter = unsafePerformIO (newIORef 0)
{-# NOINLINE counter #-}

-- Atomically increment the counter and return its current value
next :: IO Integer
next = atomicModifyIORef' counter (\ x -> (x + 1, x)) 
Data.Unique中的

base在幕后使用此实现,但不提供对基础整数的访问。在Hackage上也有各种软件包提供类似的唯一ID生成-GUID,UUID和&c。