繁体   English   中英

($)是(。),就像`fmap`是?

[英]($) is to (.) as `fmap` is to?

我有一个函数funcM :: a -> b -> c -> IO (x, y)

我想写一个函数funcM_ :: a-> b-> c-> IO x所以:

funcM_ = fst `fmap` funcM -- error

我可以添加所有要点,但似乎应该可以用fmap替换fmap某些东西,以便上面的内容起作用。 有点像用(。)替换($)会使此工作在纯上下文中进行。

我要寻找的功能是什么?

由于您要使用一个三参数函数( fmap )来构成一个单参数函数( funcM ),因此需要三个层次的合成:

funcM_ = ((fmap fst .) .) . funcM

通过简单的扩展,它等同于指向版本:

funcM_ x = (fmap fst .) . funcM x
funcM_ x y = fmap fst . funcM x y
funcM_ x y z = fmap fst (funcM x y z)

这实际上来自fmap的类型:

fmap :: (Functor f) => (a -> b) -> f a -> f b

您只是将参数部分地应用于funcM以便获得一个fa (在此为IO (x, y) ),将其赋予fmap fst以返回fbIO x )。

M_M_通常意味着返回m ()

请看以下答案: https ://stackoverflow.com/a/20279307/783743它说明了如何将代码转换为无点样式。 让我们从funcM_的非pointfree定义funcM_

funcM_ a b c = fmap fst (funcM a b c)

-- But `\x -> f (g x)` is `f . g`. Hence:

funcM_ a b = fmap fst . (funcM a b)

-- But `\x -> f (g x)` is `f . g`. Hence:

funcM_ a = (fmap fst .) . (funcM a)

-- But `\x -> f (g x)` is `f . g`. Hence:

funcM_ = ((fmap fst .) .) . funcM

做到这一点的另一种方法是使用uncurrycurry ,如下所示:

uncurry3 :: (a -> b -> c -> d) -> (a, b, c) -> d
uncurry3 f (a, b, c) = f a b c

curry3 :: ((a, b, c) -> d) -> a -> b -> c -> d
curry3 f a b c = f (a, b, c)

(.::) :: (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e
f .:: g = curry3 (f . (uncurry3 g))

现在,您可以编写funcM_ ,如下所示:

funcM_ = fmap fst .:: funcM

您还可以按如下所示以无点样式编写.:: :::

(.::) :: (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e
(.::) = (.) . (.) . (.)

希望能有所帮助。

funcM每个参数添加一个点

这些都是等效的:

((fmap fst . ) .) . funcM
((.)  . (.)  . (.))  (fmap fst) funcM
(fmap . fmap . fmap) (fmap fst) funcM

import Data.Functor.Syntax -- from 'functors' package
(.::) (fmap fst) funcM

注意,我所做的只是将隐式($)更改为(.) :-)

(.)Functor函数实例的fmap的实现:

instance Functor ((->) a) b where
  fmap f g = f . g

GHCi :t是您的朋友。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM