2017-02-20 79 views
0

我寫了數據類型和實例Monad類。下面是我的源代碼:解決Haskell中的記憶問題

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 

我遇到的問題與記憶化! 做一些事情是否可行?

+0

而對於MonadIO'實例MonadIO UI,其中 liftIO a =返回$ unsafePerformIO a' – QSpider

+1

您如何期待memoization來應對IO操作的狀態? – jakubdaniel

+1

如果有人濫用'unsafePerformIO',將不會有什麼保證:這就是爲什麼它是不安全的!只有當你不關心什麼時候或者如果IO被觸發時才能安全地使用它。爲什麼不直接使用'IO' monad呢?你甚至可以包裝它,如果你想作爲'newtype UI a = UI {unUI :: IO a}'並且圍繞它定義你的實例。 – chi

回答

5

通過使用unsafePerformIO來隱藏IO行爲中出現的效果,您故意(並且非常可能非法)進入純函數領域。在那個領域,它被允許記憶/重構。編譯器通常會盡量使用純度來避免運行時的冗餘工作。是否有真正的理由爲什麼你會隱藏這種不純物質,特別是在可以期待與外部世界(人類)互動的東西UI中?這可能表明設計不好。您的UI似乎與Identity相同,這是最簡單的仿函數,沒有任何不純效應。