将使用什么绑定运算符?

0 monads haskell

看看这个例子:

ReaderT Integer (ErrorT String (StateT Integer Identity)) Integer
Run Code Online (Sandbox Code Playgroud)

(>>=)这里将使用什么操作符绑定?
例如,如果我们使用do表示法,那么编译器会选择哪个绑定运算符?

Dav*_*vid 5

供参考,(>>=)有类型

(>>=) :: Monad m => m a -> (a -> m b) -> m b
Run Code Online (Sandbox Code Playgroud)

并注意到

ReaderT Integer (ErrorT String (StateT Integer Identity)) Integer
Run Code Online (Sandbox Code Playgroud)

是相同的

(ReaderT Integer (ErrorT String (StateT Integer Identity))) Integer
Run Code Online (Sandbox Code Playgroud)

因为类型应用程序(如函数应用程序)在Haskell中是左关联的.

所以,给定

x :: ReaderT Integer (ErrorT String (StateT Integer Identity)) Integer
Run Code Online (Sandbox Code Playgroud)

f表达式中的适当类型

x >>= f
Run Code Online (Sandbox Code Playgroud)

类型检查器将尝试匹配x左参数类型的类型(>>=).这意味着它会试图统一ReaderT Integer (ErrorT String (StateT Integer Identity)) Integer使用m a.这个统一的唯一途径是采取aIntegermReaderT Integer (ErrorT String (StateT Integer Identity)).因此,使用~类型相等表示法,我们最终得到

 m ~ (ReaderT Integer (ErrorT String (StateT Integer Identity)))
 a ~ Integer
Run Code Online (Sandbox Code Playgroud)

因此,它必须使用,where 和的(ReaderT r n)实例.Monadr ~ Integern ~ ErrorT String (StateT Integer Identity)

这是类型统一在Haskell中的工作原理的结果,而不仅仅是for (>>=),因此这个一般的想法可以用于解释其他多态函数的类型检查是如何工作的.

  • @HaskellFun不太好.如果右参数的返回类型(此处称为`f`)未使用与左参数相同的Monad实例,则编译器将给出编译器错误.此外,如果左参数的monad实例保留多态,但右参数使用特定的monad,它将根据右参数的monad进行匹配. (2认同)
  • 使用`x >> = f`,编译器会尝试将`ma`与`x`*和*`(a - > mb)`的类型匹配为`f`的类型. (2认同)
  • @HaskellFun它总是基于*两个*参数类型,它们都不比另一个更重要.如果`x :: Maybe Int`和`f :: Int - > [Bool]`,则`x >> = f`将不会进行类型检查,即使`Maybe`和`[]`都是`Monad`s .`m`不能统一为两种不同的类型. (2认同)