在 Haskell 中解决记忆问题
Solve a memoization in Haskell
我写了数据类型和实例 Monad class。下面是我的源代码:
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
我遇到了记忆问题!
可以做点什么吗?
通过使用 unsafePerformIO
来隐藏 IO
动作中效果的存在,您是在故意(而且很可能是非法的)进入纯函数领域。在那个领域,允许记忆/重构。编译器通常会尽量使用纯度来避免运行时的冗余工作。是否有真正的理由隐藏杂质,尤其是在称为 UI
的东西中,人们可以期待与外界(人类)的互动?这可能表明设计不当。您的 UI
似乎与 Identity
相同,后者是没有任何不纯效果的最简单的仿函数。
我写了数据类型和实例 Monad class。下面是我的源代码:
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
我遇到了记忆问题! 可以做点什么吗?
通过使用 unsafePerformIO
来隐藏 IO
动作中效果的存在,您是在故意(而且很可能是非法的)进入纯函数领域。在那个领域,允许记忆/重构。编译器通常会尽量使用纯度来避免运行时的冗余工作。是否有真正的理由隐藏杂质,尤其是在称为 UI
的东西中,人们可以期待与外界(人类)的互动?这可能表明设计不当。您的 UI
似乎与 Identity
相同,后者是没有任何不纯效果的最简单的仿函数。