Haskell 在没有显式方法声明的情况下,什么使fmap在这里工作?

Haskell 在没有显式方法声明的情况下,什么使fmap在这里工作?,haskell,functor,instances,Haskell,Functor,Instances,现实世界中的一个练习Haskell,第24章,要求围绕Control.Concurrent.MVar实现严格包装。正如书中所建议的,我这样做是通过使用newtypemvar包装器来确保evaluate应用于传递给函数的任何参数,例如newMVar和putMVar 现在,要包装的函数之一是mkWeakMVar,其类型是mvara->IO()->IO(弱(mvara))。假设我的MVarbuilder函数实现了严格性,我推断对于mkWeakMVar来说,将MVar放在MVar的位置就足够了。所以我写

现实世界中的一个练习Haskell,第24章,要求围绕
Control.Concurrent.MVar
实现严格包装。正如书中所建议的,我这样做是通过使用
newtype
mvar
包装器来确保
evaluate
应用于传递给函数的任何参数,例如
newMVar
putMVar

现在,要包装的函数之一是
mkWeakMVar
,其类型是
mvara->IO()->IO(弱(mvara))
。假设我的
MVar
builder函数实现了严格性,我推断对于
mkWeakMVar
来说,将
MVar
放在
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
方法声明,但这似乎是可行的。但这让我很好奇。在这种情况下,是什么使
fmap
起作用?

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

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

由于这是一个灾难性的、完全可以避免的运行时错误,因此它应该证明
-Wall

的重要性,只有在从未调用
fmap
时,它才能起作用。