【问题标题】:Solve a memoization in Haskell在 Haskell 中解决记忆
【发布时间】:2017-02-20 13:57:53
【问题描述】:

我写了数据类型和实例 Monad 类。以下是我的源代码:

data UI a = UI { unUI :: a } 
             deriving Functor


instance Applicative UI where
    pure   = UI
    m *>  k = m >>= \ _ -> k
    m <*  k = m >>= \ _ -> m
    m <*> k = UI $ (unUI m) (unUI k)


instance Monad UI where
    m >>  k = m >>= \ _ -> k
    m >>= k = k $ unUI m
    return  = UI

但是,当我使用如下功能时:

generateUUID :: UI String
generateUUID = do 
    ruuid <- liftIO $ UV4.nextRandom
    return $ UV.toString ruuid

我遇到了记忆问题! 可以做点什么吗?

【问题讨论】:

  • 对于 MonadIO instance MonadIO UI where liftIO a = return $ unsafePerformIO a
  • 您希望 memoization 如何处理 IO 动作的状态性?
  • 无法保证如果滥用unsafePerformIO会发生什么:这就是它不安全的原因!只有当您不关心 IO 何时或是否被触发时,才能安全地使用它。为什么不直接使用 IO monad 呢?你甚至可以将它包装成newtype UI a = UI { unUI :: IO a } 并围绕它定义你的实例。

标签: haskell memoization


【解决方案1】:

通过使用unsafePerformIO 隐藏IO 操作中存在的效果,您故意(并且很可能非法)进入纯函数领域。在那个领域,它被允许记忆/重构。编译器通常会尽量使用纯度以避免运行时的冗余工作。您是否有真正的理由隐藏杂质,特别是在称为UI 的东西中,人们可以期待与外部世界(人类)的互动?这可能表明设计不佳。您的 UI 似乎与 Identity 相同,这是最简单的仿函数,没有任何不纯的效果。

【讨论】:

    猜你喜欢
    • 2022-01-19
    • 2016-04-11
    • 2020-10-25
    • 2011-03-13
    • 2015-04-16
    • 2013-04-01
    • 2011-11-16
    • 2023-03-22
    • 1970-01-01
    相关资源
    最近更新 更多