我试图用lambda cyculus弄清楚为什么以下代码的函数结果
(,) <$> (+1) <*> (+1)
有类型num a => a->(a,a)而不是num a => a-> a-> a->(a,a)
这就是我所拥有的,我在做可怕的事情还是&lt;*>刚刚以这种方式连接?
( x, y -> (,) x y ) <$> ( x -> x + 1 ) <*> ( x -> x + 1 )
-- fmap applies first
(x y -> (,) ((+1) x) y ) <*> ( x -> x + 1 ) -- substituted the lambda with (+1) for better clarity
-- then goes apply
( x y -> (,) ((+1) x) ((+1) y) )
lambda的参数如何统一,什么时候?
让我们在示例中查看类型:
(,) <$> (+1) <*> (+1)
^ ^ ^
| | |
a -> b -> (a, b) Num a => a -> a Num a => a -> a
(<$>)
的 RHS和(<*>)
的RHS/LHS必须是应用函数。您的函数是Num a => (->) a
(单读读者)。
因此,在(<$>)
应用程序(伪代码)之后将是什么类型:
a -> b -> (a, b) <$> Num a => (->) a a ==> Num a => (->) a (b -> (a, b))
(<*>)
(伪代码):
Num a => (->) a (b -> (a, b)) <*> Num a => (->) a a ==> Num a => (->) a (a, a)
,但Num a => (->) a (a, a)
等于Num a => a -> (a, a)
。
正如@chi在头上写的那样,类型(->) r
的实现(<*>)
为:
(<*>) :: (->) r (a -> b) -> (->) r a -> (->) r b
f <*> g = r -> f r (g r)
,如果您申请,您将获得:
(x y -> (,) x y) <$> (r -> r + 1) <*> (r -> r + 1) =
= (r y -> (,) (r + 1) y) <*> (r -> r + 1) =
= r -> (,) (r + 1) (r + 1)