gpt4 book ai didi

haskell - 如何在 Haskell 中将函数映射到另一个函数的参数上?

转载 作者:行者123 更新时间:2023-12-03 13:11:28 25 4
gpt4 key购买 nike

所以最初我写道:

xs <- getAddrInfo (Just hints) (Just addr) (Just port)

然后在我看来,函数 'Just::a -> Maybe a' 有点像“映射”到 'hints'、'addr' 和 'port',所以我想出了这样的东西:
map_arg g f a b c = f (g a) (g b) (g c)
xs <- map_arg Just getAddrInfo hints addr port

但是 GHC 期望 (g a)、(g b) 和 (g c) 属于同一类型,因此这不会进行类型检查。

有没有办法做到这一点,或者更一般地说,有没有办法将一个函数映射到另一个函数的参数上?

最佳答案

最通用的类​​型签名看起来像

map_arg :: (forall b.b -> a b) -> (a b -> a c -> a d -> e) -> b -> c -> d -> e
map_arg g f a b c = f (g a) (g b) (g c)

对于您的情况,如果您选择不将 g 作为参数,则可以执行
map_just f a b c = f (g a) (g b) (g c) where g = Just
xs <- map_just getAddrInfo hints addr port

或者你可以只给 g 类型签名:
map_arg (g :: forall b.b -> a b) f a b c = f (g a) (g b) (g c)

要绕过多态类型签名,请记住我们有 Control.Functor.Pointed 以便您可以使用它:
map_arg :: Pointed p => (p a -> p b -> p c -> d) -> a -> b -> c -> d
map_arg f a b c = f (point a) (point b) (point c)

( PointedMaybe 实现就是你想要的 Just)

要获得通用版本,请注意
map1 :: Pointed p => (p a -> b) -> a -> b
map1 f = f . point

map2 :: Pointed p => (p a -> p b -> c) -> a -> b -> c
map2 f = map1 . map1 f

map3 :: Pointed p => (p a -> p b -> p c -> d) -> a -> b -> c -> d
map3 f = map2 . map1 f

看到了吗?您只需要 map1 而其他所有只是简单的组合!

关于haskell - 如何在 Haskell 中将函数映射到另一个函数的参数上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19533599/

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