Haskell“约束中的非类型变量参数”

Tho*_*ook 5 haskell types compiler-errors partial-application pointfree

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

listOfPartiallyAppliedFunctions = map (*) [1..100]
Run Code Online (Sandbox Code Playgroud)

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

let results = map (\x -> x 4) listOfPartiallyAppliedFunctions
Run Code Online (Sandbox Code Playgroud)

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

但是,我认为接下来可以写:

let results = map (4) listOfPartiallyAppliedFunctions
Run Code Online (Sandbox Code Playgroud)

由于不需要为地图函数提供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]
Run Code Online (Sandbox Code Playgroud)

有人可以帮我解析此错误吗?我以为4是类型构造函数Num的实例?

Wil*_*ess 8

操作员节的三个“定律”

(a `op` b)  =  (a `op`) b  =  (`op` b) a  =  op a b
Run Code Online (Sandbox Code Playgroud)

(缺少的参数进入操作员附近的空闲插槽),

或者$

a b  =  (a $ b)  =  (a $) b  =  ($ b) a  =  ($) a b
Run Code Online (Sandbox Code Playgroud)

从而

(\ x -> x 4) = (\ x -> x $ 4) = (\ x -> ($ 4) x)
Run Code Online (Sandbox Code Playgroud)

通过eta减少,就是

($ 4) 
Run Code Online (Sandbox Code Playgroud)


Wil*_*sem 7

但是,我认为接下来可以写:

let results = map (4) listOfPartiallyAppliedFunctions
Run Code Online (Sandbox Code Playgroud)

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

但是,您可以将以上内容编写为:

let results = map ($ 4) listOfPartiallyAppliedFunctions
Run Code Online (Sandbox Code Playgroud)

因此,我们在此对函数中的中缀运算符[Haskell-wiki]进行了分段($) :: (a -> b) -> a -> b