在这里,fmap如何在没有显式方法声明的情况下工作?

3
在《Real World Haskell》第24章的练习中,有一个要求在Control.Concurrent.MVar周围实现严格性包装器的练习。我正在按照书中建议的方法完成这个练习,使用newtypeMVarS包装器来确保对传递给函数(如newMVarputMVar)的任何参数都应用了evaluate
现在,其中一个需要包装的函数是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警告没有Functor Weak的显式方法声明,但这似乎可以正常工作。但是它让我感到好奇。是什么使得fmap在这种情况下工作?


2
只有在从未调用Weakfmap时,它才能正常工作。 - augustss
1个回答

10

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

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接