haskell - 应用仿函数 : why can fmap take a function with more than one argument?

标签 haskell functor applicative

我正在进入 Haskell,发现“learn you a Haskell”这本书最有帮助。我到了 applicative functors 的部分.

我对书中出现的以下内容感到困惑:

(\x y z -> [x, y, z]) <$> (+3) <*> (*2) <*> (/2) $ 5

产生输出:
[8.0,10.0,2.5]

首先,我已经在 ghci 中证实了我对运算符优先级的怀疑,因此上述内容等同于以下丑陋的陈述:
(((\x y z -> [x,y,z]) <$> (+3)) <*> (*2) <*> (/2)) $ 5 

因此,很明显发生的第一件事是fmap。调用(<$>)中缀运算符。

这是目前令我难以置信的核心。fmap的定义(这里显示为中缀 (<$>) )是:
(<$>) :: (Functor f) => (a -> b) -> f a -> f b

但在我正在努力解决的等式中,(\x y z -> [x, y, z])需要三个参数,而不仅仅是一个。那么(a -> b) 类型的第一个参数怎么可能?满意?

我认为这可能与部分应用程序/柯里化(Currying)有关,但我无法弄清楚。我将不胜感激。希望我已经很好地提出了这个问题。

最佳答案

简单的回答:Haskell 中没有具有多个参数的函数!

您可能称之为“二元函数”的候选函数有两个:一个采用(单个!)元组的函数,以及 - 迄今为止在 Haskell 中普遍存在的 - 柯里化(Currying)函数。那些只接受一个参数,但结果又是一个函数。

因此,要弄清楚例如fmap (+)是的,让我们写

type IntF = Int -> Int

-- (+) :: Int -> IntF
-- fmap :: ( a -> b  ) ->  f a -> f b
--  e.g.:: (Int->IntF) -> f Int->f IntF

在 GHCi 中自己测试:

Prelude> type IntF = Int -> Int
Prelude> let (#) = (+) :: Int -> IntF
Prelude> :t fmap (#)
fmap (#) :: Functor f => f Int -> f IntF

关于haskell - 应用仿函数 : why can fmap take a function with more than one argument?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21376085/

相关文章:

haskell - 从 Haskell 的列表中选择一个随机元素

列表到元组计数值重复和元组内的列表 - Haskell

c++ - 在 C++ 中返回仿函数的正确方法

haskell "pseudo-functor"

c++ - 创建仿函数时友元函数的可见性

haskell - 在 Haskell 中以应用风格组合验证器

haskell - 当某些变量具有特定值时分配特殊情况?

haskell - Machines 和 Conduits(或其他类似库)之间的概念区别是什么?

parsing - 应用解析器导出不带空的替代方案

haskell - 函数类似于 "when"但返回一个值?