'Referencing' 类型类函数

'Referencing' typeclass functions

我是初学者,我正在尝试使用 Hoed 来跟踪 Haskell 评估,因为它可能会进一步帮助我的学习过程。

我在他们的示例代码中看到了这样的代码

isEven :: Int -> Bool
isEven = observe "isEven" isEven'
isEven' n = mod2 n == 0

我在想我怎样才能 observe 来跟踪实例定义的函数,例如 >>=

我写了类似的东西

bind' = observe "bind'" (>>=)

当然我有一个错误

* Ambiguous type variable 'm0' arising from a use of '>>='
  prevents the constraint '(Monad m0)' from being solved.
  Relevant bindings include
    bind' :: m0 a0 -> (a0 -> m0 b0) -> m0 b0 (bound at my.hs:46:1)
  Probable fix: use a type annotation to specify what 'm0' should be.
  These potential instances exist:
  ...

我应该/如何使用类型注释来指定哪个 Monad 实例(例如 Reader、状态等)>>= 函数

看来您找到了 MonomorphismRestriction. More info。这些链接很好地解释了 MonomorphismRestriction 是什么以及它是如何工作的。

你认为没有签名的 bind' 应该 "just work" 是正确的。然而,有时编译器需要一些帮助。简而言之,由于 MonomorphismRestriction,GHC 尝试采用 bind' :: Monad m => m a -> (a -> m b) -> m b 名义上的多态签名,并通过实例化一些类型变量来降低其多态性。

在您的情况下,编译器似乎想让 bind' 仅适用于一个特定的 Monad m。没有你的真实代码,我不能肯定地说,但考虑这个例子:

import Debug.Trace

main :: IO ()
main = (>>=) (return "hello") print

bind' = trace "bind" (>>=)

编译器产生与您的类似的错误:Ambiguous type variable m0

但是,如果您使用 bind':

import Debug.Trace

main :: IO ()
main = bind' (return "hello") print

bind' = trace "bind" (>>=)

没有错误!那是因为 GHC 推断 m 应该是 IO 因为 bind'IO monad 中使用。

或者,您可以告诉 GHC 关闭 MonomorphismRestriction:

{-# LANGUAGE NoMonomorphismRestriction #-}

import Debug.Trace

main :: IO ()
main = (>>=) (return "hello") print

bind' = trace "bind" (>>=)

它编译得很好!