在Haskell中缓存函数的结果

时间:2016-07-18 08:03:37

标签: haskell

我使用以下函数生成GUID:

import Data.UUID as UV
import Data.UUID.V1 as UV1

generateUUID :: String
generateUUID = UV.toString $ fromJust $ unsafePerformIO UV1.nextUUID

我使用generateUUID来创建元素

createWidgetUI element uuid =
    WidgetUI { wui_title    = ""
             , wui_id       = uuid
             , wui_attr_style = ""
             , wui_attr_class = ""
             , wui_styles   = []
             , wui_scripts  = []
             , wui_contents = []
             , wui_children = []
             , wui_element  = element
             }

wuiPanel :: UI WidgetUI
wuiPanel = do
    return $ createWidgetUI elem uuid
    where
        uuid = generateUUID
        elem = ContainerUI $ H.div

当我多次调用方法wuiPanel时,我得到相同的UUID值!但我需要每次调用方法wuiPanel来获取具有不同UUID值的元素。我无法理解如何实现它。

1 个答案:

答案 0 :(得分:5)

我建议你重新修改UUID代,以便它适合你正在使用的UI monad。unsafe一般情况下最好避免使用 - 特别是在像你这样的情况下使用那些谎言到编译器:像String这样的类型承诺该值是一个固定的常量字符串值,允许编译器优化假设。这将使代码变得非常非常脆弱,因为它可能起作用或不起作用,具体取决于优化。

在下面的代码中,我猜测了几种类型,因此无法与您的库完全匹配。

generateUUID :: IO String
generateUUID = UV.toString . fromJust <$> UV1.nextUUID

wuiPanel :: UI WidgetUI
wuiPanel = do
    uuid <- liftIO generateUUID
    let elem = ContainerUI $ H.div
    return $ createWidgetUI elem uuid

要做的事情:更好地处理nextUUID,如果您过快地请求UUID,可能会返回Nothing“(来自文档的可怕引用)。您确定无法使用永不返回V4.nextRandom的{​​{1}}吗?