You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell表达式fmap (*3) (+5) 1求值验证请求

Got it!我来帮你一步步拆解这个Haskell表达式的求值过程,顺便把你困惑的fmap x y z语法逻辑理清楚~

先理清语法优先级:左结合的函数应用

Haskell里函数应用的优先级是最高的,而且是左结合的,所以fmap (*3) (+5) 1完全等价于((fmap (*3)) (+5)) 1——也就是说,先把(*3)传给fmap,得到一个中间函数;再把(+5)传给这个中间函数,得到最终的目标函数;最后把1传给这个目标函数得到结果。

理解函数类型的Functor实例

要搞懂这里fmap的作用,得先回忆Haskell给函数类型(->) r(也就是“从r到某个类型的函数”)定义的Functor实例:

instance Functor ((->) r) where
  fmap = (.)  -- 没错,fmap在这里就是函数组合运算符

换句话说,对于函数类型的函子,fmap f g就等于f . g(函数组合),它的作用是把f“套”在g的输出上——也就是先运行g得到结果,再把这个结果传给f。

一步步求值

现在我们把规则套到表达式里:

  • 第一步:计算fmap (*3) (+5)
    根据上面的实例,这等价于(*3) . (+5),也就是一个新函数,逻辑是“接收一个数x,先算x+5,再把结果乘以3”。
  • 第二步:把这个新函数应用到1上
    ((*3) . (+5)) 1按照函数组合的定义,等价于(*3) ((+5) 1)
  • 第三步:计算内层的(+5) 1,得到6
  • 第四步:最后计算(*3) 6,得到18
从类型角度再验证(帮你加深理解)
  • (*3)的类型是Num a => a -> a(接收一个数值,返回它的3倍)
  • (+5)的类型是Num a => a -> a(接收一个数值,返回它加5的结果)
  • fmap作用在(*3)上后,类型变成Num a => (a -> a) -> (a -> a)(接收一个a->a的函数,返回另一个a->a的函数)
  • 把(+5)传给这个函数,得到的最终函数类型还是Num a => a -> a,最后传入1就得到了18

这样是不是就把整个逻辑理清楚啦?

内容的提问来源于stack exchange,提问作者Šefčíková Jana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:50:50