求解析Haskell中fmap . const的类型推导与行为逻辑
解析
<$>运算符的类型与行为 一、类型推导步骤
先明确各个基础函数的类型(为避免变量名冲突,统一调整占位符):
const:const :: a -> b -> a—— 接受第一个参数后,返回该参数,完全忽略第二个参数fmap:fmap :: Functor f => (x -> y) -> f x -> f y—— Functor的核心函数,将普通函数映射到容器上- 函数组合
(.):(.) :: (y -> z) -> (x -> y) -> x -> z—— 把两个函数串联,g . h等价于\x -> g (h x)
现在推导fmap . const的类型:
- 首先展开函数组合:
fmap . const = \val -> fmap (const val) - 看
const val的类型:当传入val :: b时,const val的类型是forall a. a -> b(无论第二个参数是什么类型,都返回val) - 将
const val作为参数传入fmap:fmap需要的参数是(x -> y),这里x对应a,y对应b,所以fmap (const val)的类型是f a -> f b - 整合起来,整个表达式
\val -> (f a -> f b)的类型就是b -> f a -> f b,也就是题目里的预期类型Functor f => b -> f a -> f b
二、实际行为理解
<$的本质是用一个固定值替换容器内的所有元素,同时保留容器的结构。举几个直观例子:
- 列表容器:
"hello" <$ [1,2,3]→["hello", "hello", "hello"] - Maybe容器:
42 <$ Nothing→Nothing;42 <$ Just "foo"→Just 42 - Either容器:
"new" <$ Left "err"→Left "err"(Left属于Either的“错误分支”,Functor不会修改它);"new" <$ Right 100→Right "new"
简单来说,<$就是“把容器里的东西全换成我给的值,容器本身不变”。
内容的提问来源于stack exchange,提问作者csh
相关产品推荐
相关产品推荐

