Haskell中Applicative Functor表达式展开验证及相关疑问
问题解答
展开过程是否正确?
这个展开过程是完全正确的,具体依据如下:
- 在
Maybe的Applicative实例实现中,pure f等价于Just f,所以pure (+)可以直接替换为Just (+)。 <*>在Maybe中的规则是:Just f <*> Just x = Just (f x),非Just的情况结果都是Nothing。因此Just (+) <*> Just 1会把(+)部分应用到1上,得到Just (1+)(也就是Just (\x -> 1 + x))。- 最后
Just (1+) <*> Just 2会把这个偏函数应用到2上,最终得到Just 3。
为什么(Just (+)) <*> (Just 2)无法直接执行?
核心问题出在类型推断的模糊性上:
(+)的类型是Num a => a -> a -> a,所以Just (+)的类型是Num a => Maybe (a -> a -> a),Just 2的类型是Num b => Maybe b。- 执行
<*>时,类型检查器会要求a和b统一,此时表达式的结果类型是Num a => Maybe (a -> a)——这个类型本身是合法的,但Haskell无法自动推断出具体的a是什么(比如是Int还是Double),因为没有后续代码来约束这个类型参数。
解决起来很简单,要么给表达式加类型注解明确指定类型:
(Just (+) :: Maybe (Int -> Int -> Int)) <*> (Just 2)
要么继续用<*>结合另一个Maybe值,让类型检查器能自动推断:
(Just (+)) <*> (Just 2) <*> (Just 3) -- 结果为Just 5
内容的提问来源于stack exchange,提问作者Rifat Ahmed
相关产品推荐
相关产品推荐

