在Haskell中解决一个记忆问题
我编写了数据类型和实例Monad类。下面是我的源代码:在Haskell中解决一个记忆问题,haskell,memoization,Haskell,Memoization,我编写了数据类型和实例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
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
data UI a=UI{unUI::a}
派生函子
实例应用程序UI,其中
纯=用户界面
m*>k=m>>=\\ uUK->k
m>=\\->UM
m k=UI$(联合国大学m)(联合国大学k)
实例Monad用户界面,其中
m>>k=m>>=\\ uUK->k
m>>=k=k$unUI m
返回=用户界面
但是,当我使用如下函数时:
generateUUID :: UI String
generateUUID = do
ruuid <- liftIO $ UV4.nextRandom
return $ UV.toString ruuid
generateUID::UI字符串
generateuid=do
ruuid通过使用unsafePerformIO
隐藏IO
操作中的效果,您故意(很可能是非法)进入纯函数领域。在这个领域,它被允许记忆/重构。编译器通常会尽量使用纯净度,以避免运行时的冗余工作。有没有真正的原因让你隐藏这些杂质,特别是在一个叫做UI
的东西中,人们可以期待与外部世界(人类)的交互?这可能表明设计不好。您的UI
似乎与Identity
相同,后者是没有任何不纯效果的最简单的函子。通过使用unsafePerformIO
隐藏IO
操作中的效果,您故意(很可能是非法)进入纯函数领域。在这个领域,它被允许记忆/重构。编译器通常会尽量使用纯净度,以避免运行时的冗余工作。有没有真正的原因让你隐藏这些杂质,特别是在一个叫做UI
的东西中,人们可以期待与外部世界(人类)的交互?这可能表明设计不好。您的UI
似乎与Identity
相同,后者是没有任何不纯效果的最简单的函子。对于MonadIO实例MonadIO UI,liftIO a=return$unsafePerformIO a
您希望备忘录如何处理IO
操作的状态性?无法保证会发生什么如果有人滥用unsafePerformIO
:这就是它不安全的原因!只有当您不关心IO何时或是否被触发时,才能安全地使用它。为什么不直接使用IO
monad呢?如果需要,您甚至可以将其包装为newtypeuia=UI{unUI::ioa}
并围绕此定义实例。对于MonadIO实例MonadIO UI,liftIO a=return$unsafePerformIO a
您希望备忘录如何处理IO
操作的状态性?如果滥用unsafePerformIO
,则无法保证会发生什么:这就是它不安全的原因!只有当您不关心IO何时或是否被触发时,才能安全地使用它。为什么不直接使用IO
monad呢?如果需要,您甚至可以将其包装为newtypeuia=UI{unUI::ioa}
,并围绕它定义实例。