Haskell "Non type-variable argument in the constraint"

Haskell "Non type-variable argument in the constraint"

我在我的 REPL 中创建了一个部分应用的函数列表,如下所示:

listOfPartiallyAppliedFunctions = map (*) [1..100]

然后我想创建完成函数应用程序的结果列表,我可以通过向地图函数提供一个 lambda 轻松地做到这一点,如下所示:

let results = map (\x -> x 4) listOfPartiallyAppliedFunctions

这基本上意味着将应用于 4 的函数 x 映射到部分应用函数列表上,其中 x 是列表中的每个部分应用函数。

然而,我认为接下来我可以写:

let results = map (4) listOfPartiallyAppliedFunctions

因为不需要为 map 函数提供 lambda,因为它应该知道将 4 应用于 listOfPartiallyAppliedFunctions.

中包含的部分应用函数

但是,我收到此错误:

• Non type-variable argument in the constraint: Num ((a -> a) -> b)
  (Use FlexibleContexts to permit this)
• When checking the inferred type
    it :: forall a b. (Num a, Num ((a -> a) -> b), Enum a) => [b]

有人可以帮我解析这个错误吗?我以为 4 是类型构造函数 Num?

的一个实例

However, I thought it would then follow that I could write:

let results = map (4) listOfPartiallyAppliedFunctions

不,如果你会执行 \x -> 4 x,你可以将其替换为 4。但是由于 4 意味着它是一个 Num 实例,并且您可能没有将函数 a -> b 设为 Num 的实例,编译器无法解决这个问题。因此,编译器说它没有找到将数字 4 转换为函数的方法,而且绝对不是将函数 Num a => a -> a 作为输入然后将其转换为 [=19] 的函数=].

但是你可以把上面的写成:

let results = map <b>($ 4)</b> listOfPartiallyAppliedFunctions

这里我们执行一个sectioning of an infix operator [Haskell-wiki] on the ($) :: (a -> b) -> a -> b函数。

Three "laws" of operator sections

(a `op` b)  =  (a `op`) b  =  (`op` b) a  =  op a b

(缺少的参数进入运算符附近的空闲槽),

或与$

a b  =  (a $ b)  =  (a $) b  =  ($ b) a  =  ($) a b

因此

(\ x -> x 4) = (\ x -> x $ 4) = (\ x -> ($ 4) x)

并且 eta-reduction 是

($ 4)