【问题标题】:Too many arguments for fmapfmap 的参数太多
【发布时间】:2019-11-17 00:12:27
【问题描述】:

fmap 的第一个参数是一个带有一个参数的函数。

fmap :: Functor f => (a -> b) -> f a -> f b

然后我在前奏中尝试如下:

Prelude> x = fmap (\x y -> x * y)

如您所见,fmap 的第一个参数是一个函数,它有两个参数。为什么编译器让它通过?

上面我传递给fmap的函数有两个参数,不是一个!

【问题讨论】:

  • 因为在 Haskell 中,所有函数都被认为是 curried
  • 这是对 arity 的抽象,这对于支持一流函数的语言是可能的。您不必关注多参数函数的数量,而必须关注函数序列。
  • 这实际上是在应用程序的 Haskell 中很常见的事情。 f <$> x <*> y 表示 fmap f x <*> y。例如,(*) <$> [2, 3] <*> [5, 7] 表示[(2 *), (3 *)] <*> [5, 7],其计算结果为[2 * 5, 2 * 7, 3 * 5, 3 * 7][10, 14, 15, 21]

标签: haskell functor


【解决方案1】:

Haskell 实际上并没有多于(或少于)一个参数的函数。 “双参数函数”实际上只是一个接受一个参数并产生另一个接受另一个参数的函数的函数。也就是说,\x y -> x * y 只是\x -> \y -> x * y 的语法捷径。这个概念被称为柯里化。

所以这应该解释你的例子中发生了什么。您的fmap 将简单地将f 的数字转换为f 的函数。因此,例如,x [1,2,3] 将生成列表[\y -> 1 * y, \y -> 2 * y, \y -> 3 * y](又名[(1*), (2*), (3*)])。

【讨论】:

    【解决方案2】:

    您已经定义了一个函数。函数式编程的基本方面之一,即函数可以是参数、存储到变量等。

    如果我们接着查询x类型,我们会得到:

    Prelude> :t x
    x :: (Functor f, Num a) => f a -> f (a -> a)
    

    所以x 现在是一个函数,它以 Functor 为输入,a 应用于该函数,并返回具有相同仿函数但已应用的类型的元素a -> a

    因此您可以在x应用列表,例如:

    Prelude> :t x [1,4,2,5]
    x [1,4,2,5] :: Num a => [a -> a]
    

    所以现在我们有一个函数列表,即等价于

    [\x -> 1*x, \x -> 4*x, \x -> 2*x, \x -> 5*x]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多