是什么让fmap在没有显式方法声明的情况下工作?

时间:2014-10-06 17:10:28

标签: haskell functor instances

Real World Haskell 中的一个练习,ch。 24,要求在Control.Concurrent.MVar周围实现严格包装。我正如本书中所建议的那样,使用newtype MVarS包装器来确保将evaluate应用于传递给newMVar等函数的任何参数。 putMVar

现在,要包装的函数之一是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警告fmap Functor Weak没有明确的方法声明。但这让我很感兴趣。是什么让fmap在这种情况下起作用?

1 个答案:

答案 0 :(得分:10)

虽然上面的代码会进行类型检查,但在尝试评估需要调用缺少的fmap实现的值时,GHC会崩溃。它看起来有点像:

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

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