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

Pab*_*blo 3 haskell functor instances

真实世界Haskell中的一个练习,ch.24,要求实现严格的包装Control.Concurrent.MVar.我正如本书中所建议的那样,通过使用newtype MVarS包装器确保将evaluate其应用于传递给诸如newMVar和等函数的任何参数putMVar.

现在,要包装的函数之一是mkWeakMVar,其类型是MVar a -> IO () -> IO (Weak (MVar a)).假设我的MVarS构建函数实现严格,我推断,因为mkWeakMVar它足以MVarS代替它的MVars.所以我写了以下内容:

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)
Run Code Online (Sandbox Code Playgroud)

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

J. *_*son 10

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

*** Exception: /Users/tel/tmp/SO.hs:31:10-18: 
    No instance nor default method for class operation GHC.Base.fmap
Run Code Online (Sandbox Code Playgroud)

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