2014-10-06 111 views
3

其中的练习真实世界哈斯克尔,ch。 24,要求实施严格的包装Control.Concurrent.MVar。正如书中所建议的那样,我正在使用newtypeMVarS包装来确保evaluate适用于传递给函数的任何参数,如newMVarputMVar什么使fmap在没有明确的方法声明的情况下工作?

现在,要包装的功能之一是mkWeakMVar,其类型为MVar a -> IO() -> IO (Weak (MVar a))。假设我的MVarS构建函数实现了严格性,我推断对于mkWeakMVar,只需将MVarS代替它的MVar即可。所以我写了以下内容:

import   Control.Concurrent.MVar 
import   System.Mem.Weak 

instance Functor Weak 

newtype MVarS a = MVarS (MVar a) 

mkWeakMVarS :: MVarS a -> IO() -> IO (Weak (MVarS a)) 
mkWeakMVarS (MVarS mv) x = (fmap . fmap) MVarS (mkWeakMVar mv x) 

这似乎工作,即使GHCI警告说,存在的fmapFunctor Weak没有明确的方法声明。但它让我很感兴趣。是什么让fmap在这种情况下工作?

+2

只有'Weak'的'fmap'永远不会被调用。 – augustss 2014-10-06 17:19:45

回答

10

虽然上面的代码会检查,但当试图评估需要调用缺失的fmap实现的值时,GHC会崩溃。它会看起来有点像:

*** Exception: /Users/tel/tmp/SO.hs:31:10-18: 
    No instance nor default method for class operation GHC.Base.fmap 

由于这是一个相当灾难性和完全可以避免的运行时错误它应该作为证明的-Wall的重要性。

相关问题