[英]About mapping on the eventual result of a multi-argument function
I known that r -> a
is a Functor
in a
, and that fmap = (.)
for it.我知道
r -> a
是 a 中a
仿函数,并且Functor
fmap = (.)
是它。
This means that when I do fmap fg
, with g:: r -> a
, f
is applied to the result of g
as soon as the latter is fed with a value of type r
.这意味着当我使用
g:: r -> a
执行fmap fg
时,只要将 g 的值输入r
类型的值,就会将f
应用于g
的结果。 However, if a
is a function type, eg a unary function b -> c
, then there's a difference between applying f
to that function (which is what happens in reality) and applying f
to the eventual result of g
(which could be desirable in some cases; couldn't it?). However, if
a
is a function type, eg a unary function b -> c
, then there's a difference between applying f
to that function (which is what happens in reality) and applying f
to the eventual result of g
(which could be desirable在某些情况下;不是吗?)。
How do I map on the eventual result of g
?我如何 map 对
g
的最终结果? In this case of g:: r -> b -> c
it seems easy, I can just uncurry $ fmap f $ curry g
.在这种情况下
g:: r -> b -> c
看起来很容易,我可以uncurry $ fmap f $ curry g
。 But what if also c
is a function type?但是,如果
c
也是 function 类型怎么办?
Or, in other words, how do I map on the final result of multi-variable function?或者,换句话说,我如何 map 对多变量 function 的最终结果? Is the
curry
/ uncurry
trick necessary/doable in general?一般来说,
curry
/ uncurry
技巧是必要的/可行的吗?
(Related question here .) (相关问题在这里。)
As it's apparent from comments/answers, I have not realized I was essentially asking the same question I've already asked some days ago.从评论/答案中可以明显看出,我没有意识到我本质上是在问我几天前已经问过的同一个问题。 Probably it was not apparent to me because of how I got here.
由于我是如何到达这里的,这对我来说可能并不明显。 Essentially, what led me to ask this question is another one storming in my head:
从本质上讲,导致我提出这个问题的是另一个在我脑海中闪过的问题:
If I can use liftA2 (&&)
, liftA2 (||)
, and similar to combine unary predicates, how do I combine binary predicates?如果我可以使用
liftA2 (&&)
、 liftA2 (||)
和类似的组合一元谓词,我如何组合二元谓词? To answer to this, I played around a bit in GHCi, and came up with this为了回答这个问题,我在 GHCi 中玩了一下,然后想出了这个
liftIntoBinaryFunc p = \q r -> curry $ (liftA2 p) (uncurry q) (uncurry r)
which would allow doing something like this:这将允许做这样的事情:
-- some binary predicate
distanceLE3 x y = 3 >= abs (x - y)
sameSign x y = ((==) `on` signum) x y
-- function to lift into binary functions
liftIntoBinaryFunc p = \q r -> curry $ (liftA2 p) (uncurry q) (uncurry r)
-- lifting && into binary functions to Bool
and' = liftIntoBinaryFunc (&&)
-- combining
pred = distance3 `and'` sameSign
-- using
p 3 18 -- False
p 3 1 -- True
p 3 (-1) -- False
However, this question too generalizes to how do I combine predicates of arbitrary (though common) arity?但是,这个问题太笼统地概括为如何组合任意(尽管常见)的谓词? , and probably the answer is the same.
,而且可能答案是一样的。
If you'd like to accept n arguments and then apply f
, you may call fmap
n times.如果您想接受n arguments 然后应用
f
,您可以调用fmap
n次。 So, if g:: r -> b -> c
, then所以,如果
g:: r -> b -> c
,那么
(fmap . fmap) f g
will apply f
to the value of type c
that results from applying g
to two arguments, while if h:: a -> b -> c -> d -> e -> f -> g
, then将
f
应用于c
类型的值,该值将g
应用于两个 arguments,而如果h:: a -> b -> c -> d -> e -> f -> g
a b c d e f
(fmap . fmap . fmap . fmap . fmap . fmap) f h
will apply f
to the value of type g
that results from applying h
to 6 arguments.将
f
应用于将h
应用于 6 arguments 所产生的类型g
的值。
r -> b -> c
is r -> (b -> c)
and so (fmap. fmap) (f:: c -> d) (g:: r -> b -> c):: r -> b -> d
: r -> b -> c
is r -> (b -> c)
and so (fmap. fmap) (f:: c -> d) (g:: r -> b -> c):: r -> b -> d
:
> foo :: (c -> d) -> (r -> (b -> c)) -> r -> (b -> d) ;
foo = fmap . fmap
foo :: (c -> d) -> (r -> b -> c) -> r -> b -> d
> bar :: (c -> d) -> (r -> (b -> (t -> c))) -> r -> (b -> (t -> d)) ;
bar = fmap . fmap . fmap
bar :: (c -> d) -> (r -> b -> t -> c) -> r -> b -> t -> d
But you will have to know how many nested levels are there, to compose the fmaps
accordingly, or use approaches from your other recent question .但是您必须知道有多少嵌套级别,才能相应地组合
fmaps
,或者使用您最近的其他问题中的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.