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

时间:2019-07-09 14:45:41

标签: haskell types compiler-errors pointfree partial-application

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

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

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

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

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

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

let results = map (4) listOfPartiallyAppliedFunctions

由于不需要为映射函数提供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的实例?

2 个答案:

答案 0 :(得分:7)

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归约法是

($ 4) 

答案 1 :(得分:6)

  

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

let results = map (4) listOfPartiallyAppliedFunctions

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

不过,您可以将上面的代码写为:

b

因此,我们在此sectioning of an infix operator [Haskell-wiki]函数上执行($) :: (a -> b) -> a -> b