如何解决关于多参数函数最终结果的映射
我知道 r -> a
是 Functor
中的 a
,并且它是 fmap = (.)
。
这意味着当我使用 fmap f g
执行 g :: r -> a
时,一旦 f
的值被输入类型为g
。但是,如果 r
是函数类型,例如一个一元函数 a
,那么将 b -> c
应用于该函数(这是实际发生的情况)和将 f
应用于 f
的最终结果(其中在某些情况下可能是可取的;不是吗?)。
如何映射 g
的最终结果?在这种情况下 g
似乎很容易,我可以只 g :: r -> b -> c
。但是如果 uncurry $ fmap f $ curry g
也是一个函数类型呢?
或者,换句话说,我如何映射到多变量函数的最终结果? c
/curry
技巧在一般情况下是否必要/可行?
(相关问题 here。)
从评论/答案中可以明显看出,我还没有意识到我实际上在问几天前我已经问过的同一个问题。可能这对我来说并不明显,因为我如何来到这里。本质上,是什么让我问这个问题是另一个在我脑海中猛冲的:
如果我可以使用 uncurry
、liftA2 (&&)
和类似的组合一元谓词,我该如何组合二元谓词? 为了回答这个问题,我玩了一会儿在 GHCi 中,并想出了这个
liftA2 (||)
这将允许做这样的事情:
liftIntoBinaryFunc p = \q r -> curry $ (liftA2 p) (uncurry q) (uncurry r)
然而,这个问题过于概括为我如何组合任意(虽然常见)元数的谓词?,而且答案可能是相同的。
解决方法
如果您想接受 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 -> c
是 r -> (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 的方法。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。