关于映射到多参数函数的最终结果

About mapping on the eventual result of a multi-argument function

我知道 r -> aa 中的 Functor,并且 fmap = (.) 是它的

这意味着当我使用 g :: r -> a 执行 fmap f g 时,一旦 g 被赋予一个值,f 就会应用于 g 的结果类型 r。但是,如果 a 是函数类型,例如一元函数 b -> c,然后将 f 应用于该函数(这是实际发生的情况)和将 f 应用于 g 的最终结果(这在某些情况下可能是可取的;不是吗?)。

如何映射 g 的最终结果?在这种情况下 g :: r -> b -> c 似乎很容易,我可以 uncurry $ fmap f $ curry g。但是如果 c 也是一个函数类型呢?

或者换句话说,如何映射到多变量函数的最终结果? curry/uncurry 技巧 necessary/doable 一般吗?

(相关问题。)

从 comments/answers 可以明显看出,我没有意识到我本质上是在问我几天前已经问过的同一个问题。可能因为 我是如何 来到这里的,所以对我来说并不明显。本质上,是什么让我问这个问题是另一个在我脑海中席卷而来的问题:

如果我可以使用 liftA2 (&&)liftA2 (||) 和类似的组合一元谓词,我该如何组合二元谓词? 要回答这个问题,我在 GHCi 中玩了一下,想出了这个

liftIntoBinaryFunc p = \q r -> curry $ (liftA2 p) (uncurry q) (uncurry r)

这将允许做这样的事情:

-- 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

但是,这个问题也概括为 我如何组合任意(虽然常见)元数的谓词?,答案可能是相同的。

如果您想接受 n 个参数然后应用 f,您可以调用 fmap n 次。所以,如果 g :: r -> b -> c,那么

(fmap . fmap) f g

f 应用于类型 c 的值,该值由将 g 应用于两个参数而产生,而如果 h :: a -> b -> c -> d -> e -> f -> g,则

   a      b      c      d      e      f
(fmap . fmap . fmap . fmap . fmap . fmap) f h

f 应用到类型 g 的值,该值是将 h 应用到 6 个参数的结果。

r -> b -> cr -> (b -> c) 所以 (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

但是您必须知道有多少嵌套级别,才能相应地组成 fmaps,或者使用其他 recent question.

的方法