所以最初我写道:
xs <- getAddrInfo (Just hints) (Just addr) (Just port)
Run Code Online (Sandbox Code Playgroud)
那么在我看来,函数'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
Run Code Online (Sandbox Code Playgroud)
但GHC期望(ga),(gb)和(gc)属于同一类型,因此不进行类型检查.
有没有办法做到这一点,或者更一般地说,有没有办法将函数映射到另一个函数的参数?
最通用的类型签名看起来像
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)
Run Code Online (Sandbox Code Playgroud)
对于您的情况,如果您选择不g作为参数,您可以这样做
map_just f a b c = f (g a) (g b) (g c) where g = Just
xs <- map_just getAddrInfo hints addr port
Run Code Online (Sandbox Code Playgroud)
或者你只能给出类型签名g:
map_arg (g :: forall b.b -> a b) f a b c = f (g a) (g b) (g c)
Run Code Online (Sandbox Code Playgroud)
要绕过多态类型签名,请记住我们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)
Run Code Online (Sandbox Code Playgroud)
(Pointedfor 的实现Maybe是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
Run Code Online (Sandbox Code Playgroud)
看到了吗?你只需要map1和所有其他人只是简单的组合!
| 归档时间: |
|
| 查看次数: |
172 次 |
| 最近记录: |