我对 GHC 用户指南的“隐式参数和多态递归”一章有疑问。
代码是
len1 :: [a] -> Int
len1 xs = let ?acc = 0 in len_acc1 xs
len_acc1 [] = ?acc
len_acc1 (_:xs) = let ?acc = ?acc + (1::Int) in len_acc1 xs
------------
len2 :: [a] -> Int
len2 xs = let ?acc = 0 in len_acc2 xs
len_acc2 :: (?acc :: Int) => [a] -> Int
len_acc2 [] = ?acc
len_acc2 (_:xs) = let ?acc = ?acc + (1::Int) in len_acc2 xs
章节说
在前一种情况下,len_acc1 在它自己的右手边是单态的,所以隐式参数 ?acc 不会传递给递归调用。在后一种情况下,由于 len_acc2 具有类型签名,因此对多态版本进行递归调用,该版本将 ?acc 作为隐式参数。
问题是
在这种情况下,“单态在它自己的右手边”是否意味着类型
len_acc1 :: (?acc :: Int) => [a] -> p
?为什么ghci说len_acc1 :: (?acc::Int) => [a] -> Int
?为什么第一个函数是单态的,而第二个不是?如果我的理解是正确的,反之亦然。
或者可能意味着类型是
len_acc1 :: [a] -> Int
,但每种情况都指的是?acc
隐式值,所以我认为类型应该提到(?acc :: Int)
约束。这种单态性如何暗示隐式参数没有传递给函数?