我正在做一篇过去的论文,对这个问题感到非常困惑:
我尝试研究它,查看帖子,观看 YouTube 视频,但我仍然不明白它,这让我更加困惑。
Pairer 接受任何类型的值并返回该值的列表:
pairer :: a -> [a]
现在左侧配对器的返回类型作为第一个配对器应用程序的输入结果,但这返回一个
[a]
并且配对器需要一个 a
,这是不兼容的,因为第一个配对器的域需要与第二个的域匹配
有人可以解释一下
pairer . pairer
如何有效吗?
我试图跟进,但没有理解它,就像我上面所说的那样,据我所知,应用的第一个函数的返回类型需要匹配第二个函数的域
多态(或泛型)函数实际上是一个无限的函数族。你的函数具有多态类型
pairer :: forall a . a -> [a]
因此它作为函数族工作
pairer @Int :: Int -> [Int]
pairer @Bool :: Bool -> [Bool]
pairer @[Int] :: [Int] -> [[Int]]
pairer @(Int -> Bool) :: (Int -> Bool) -> [Int -> Bool]
...
其中类型变量
a
专门用于所有可能的类型。这里绝对允许任何类型来替换 a
。
因此,成分有可能
pairer @A . pairer @B
类型良好:因为
pairer @B
的共域与 pairer @A
的共域重合就足够了,当 A = [B]
时就是这种情况。
现代 Haskell 允许显式指定所需的实例化(
@...
中的 pairer @...
),但也允许程序员忽略这一点并要求编译器推断它(类型推断)。因此,我们也可以写
pairer . pairer
编译器会弄清楚它,选择两种不同的专业化来进行类型检查。我们在这里并没有真正与自身组合相同的函数,因为它的共域与域不同——我们需要两个兼容的专业化。