“重载签名与单态限制冲突”

Fut*_*iti 9 haskell monomorphism-restriction

为什么允许这样做:

i :: Num a => a
i = 1
Run Code Online (Sandbox Code Playgroud)

虽然这些都是不允许的:

i' :: Num a => a
Just i' = Just 1

x, y :: Num a => a
(x, y) = (1, 2)

x :: Num a => a
y :: Num a => a
(x, y) = (1, 2)

y :: Num a => a
x :: Num a => a
(x, y) = (1, 2)

m :: ()
n :: Num a => a
(n, m) = (1, ())

n :: Num a => a
m :: ()
(n, m) = (1, ())
Run Code Online (Sandbox Code Playgroud)

除非通过 关闭单态限制{-# LANGUAGE NoMonomorphismRestriction #-},否则尝试使用其中任何一个进行编译总是会导致“重载签名与单态限制冲突”。

但我不是已经在这里指定了所有类型吗?单态限制首先是怎么出现的呢?

n. *_* m. 6

引用规则:

我们说给定的声明组是不受限制的当且仅当:
(a):组中的每个变量都由函数绑定或简单模式绑定(第 4.4.3.2 节)绑定,并且
(b):显式类型签名为组中通过简单模式绑定绑定的每个变量给出。

什么是简单的模式绑定?有两个相互矛盾的定义。

(4.5.5 单态性限制)简单模式绑定是其中模式仅由单个变量组成的模式绑定

(4.4.3.2 模式绑定) 简单的模式绑定具有形式p = e

根据第一个定义,失败的绑定都不是简单的,因此它们不能不受限制,这意味着单态限制适用于它们。根据第二个定义,一切都是简单且不受限制的,即不应该应用单态性限制。

适用的定义应该是本文中详细介绍的第一个定义,这就是编译器正在使用的定义,但 AFAICT 报告未更新以反映这一点。