gpt4 book ai didi

haskell - 如何派生 `liftM2 fmap zip . mapM` 的类型?

转载 作者:行者123 更新时间:2023-12-04 04:33:22 26 4
gpt4 key购买 nike

我最近需要以下功能。这个想法是拉上原来的xs值以及 mapM f xs值。

zipMapM f xs = fmap (zip xs) (mapM f xs)

把它通过pointfree,我得到了什么,或者我,似乎是一个难以理解但简单的结果:
zipMapM = liftM2 fmap zip . mapM

所以我试图弄清楚:
liftM2 :: Monad m   => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
fmap :: Functor f => (a -> b) -> f a -> f b
zip :: [a] -> [b] -> [(a, b)]
mapM :: Monad m => (a -> m b) -> [a] -> m [b]

从这里开始:
liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 fmap :: (Monad m, Functor f) => m (a -> b) -> m (f a) -> m (f b)

到目前为止还好。下一步让我难住了:
liftM2 fmap zip :: Functor f => ([a] -> f [b]) -> [a] -> f [(a, b)]

这是如何推导出来的?然后进一步走向最终功能?

最佳答案

liftM2正在做大部分魔术。在“函数 Monad”中,((->) a) , liftM2看起来像这样

liftM2 h f g x = h (f x) (g x)

我们可以用它来立即消除 xs
zipMapM f xs = fmap (zip xs) (mapM f xs)
zipMapM f xs = liftM2 fmap zip (mapM f) xs
zipMapM f = liftM2 fmap zip (mapM f)

然后如果我们想到 liftM2 fmap zip作为一个完全独立的函数,这正是 (.) 的定义
(g . f) x = g (f x) -- gives us

zipMapM f = (liftM2 fmap zip . mapM) f

我们可以减少
zipMapM = liftM2 fmap zip . mapM

关于haskell - 如何派生 `liftM2 fmap zip . mapM` 的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20170563/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com