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

Haskell中(+) <$> (+3) <*> (*100)函子表达式含义解析

解读Haskell表达式 :t (+) <$> (+3) <*> (*100)

首先你对优先级和结合性的判断完全正确:<$>和<*>优先级相同且左结合,所以这个表达式确实等价于((+) <$> (+3)) <*> (*100)。下面一步步拆解它的作用:

1. 先看 (+) <$> (+3)

<$>是fmap的中缀形式,对于函数类型(这里属于Reader Monad范畴),fmap f g的行为是把f作用在g的输出上:

  • (+)的类型是Num a => a -> a -> a,是一个接受第一个数、返回“等待第二个数的加法函数”的二元函数;
  • (+3)的类型是Num a => a -> a,是接受一个数x、返回x+3的函数。

用fmap把(+)映射到(+3)上,得到的结果是\x -> (+) (x+3)——也就是一个接受x、返回“等待第二个数y,计算(x+3)+y”的函数,类型为Num a => a -> a -> a。

2. 再看和(*100)的<*>运算

<*>是Applicative的中缀操作符,对于函数类型,它的定义是f <*> g = \x -> f x (g x)——简单说就是让左右两个函数共享同一个输入x,然后把左边函数的输出(一个函数)应用到右边函数的输出上。

把第一步得到的\x -> (x+3)+和(*100)代入<*>,展开后就是:

\x -> (x+3) + (x*100)

简化后为\x -> 101*x + 3,类型是Num a => a -> a。

关于《Learn You a Haskell for Great Good》里的描述

书中说“将+用于(+10)和(+5)的未来返回值”,这是从Applicative/Reader Monad的“共享环境”角度解释的:

  • (+)是我们要执行的二元操作,<$>先把它和左边的(+10)绑定,相当于“先记住要把(+10)的结果作为+的第一个参数”;
  • <*>再把右边的(+5)绑定过来,相当于“再记住要把(+5)的结果作为+的第二个参数”;
  • 最终得到的是一个“等待输入x”的函数,当x传入时,同时计算x+10和x+5,再把它们相加。

这个描述和左结合的计算逻辑完全一致——左结合只是运算的顺序,本质是Applicative让两个函数共享同一个输入,把二元操作的两个参数分别绑定到两个函数的输出上,最后合并结果。

内容的提问来源于stack exchange,提问作者helloword

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 17:05:59