操作参数的顺序来构造函数类型 [英] Manipulating the order of arguments to type constructors

查看:111
本文介绍了操作参数的顺序来构造函数类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 实例Functor(或e)其中

fmap _ (左a)=留下

fmap f(右b)=右(fb)

如果我希望 fmap 只有在 Left 时才更改该值,我该怎么做?



我的意思是,我用什么语法来表示我使用类型或者_ b 而不是无论是_

解决方案

我不认为有办法做到这一点直接,不幸的是。使用一个函数,你可以使用 flip 来部分应用第二个参数,但这不适用于类型构造函数,比如或者
$ b

最简单的事情可能是将它包装在 newtype 中:

  newtype镜像ba =镜像(或ab)

实例Functor(镜像e)其中
fmap _(镜像(右))= Mirrored $ Right a
fmap f(Mirrored(Left b))= Mirrored $ Left(fb)

使用 newtype 包装也是为单个类型创建多个实例的标准方式,例如 Sum Product Monoid 的实例。否则,每个类型只能有一个实例。



另外,根据您想要做什么,另一个选项是忽略 Functor



















$ :(a - > c) - > (b→d)→> f a b - > fcd

实例Bifunctor要么
bimap f _(Left a)= Left $ fa
bimap _ g(Right b)= Right $ gb

实例Bifunctor(,)其中
bimap fg(a,b)=(fa,gb)



显然,这个类比常规的 Functor 有两倍的乐趣。当然,你不能很容易地制作 Monad 实例。


I wrote something like this:

instance Functor (Either e) where

   fmap _ (Left a) = Left a

   fmap f (Right b) = Right (f b)

How do I do the same if I want fmap to change the value only if it's Left?

I mean, what syntax do I use to indicate that I use type Either _ b instead of Either a _?

解决方案

I don't think there's a way to do that directly, unfortunately. With a function you can use flip to partially apply the second argument, but that doesn't work with type constructors like Either.

The simplest thing is probably wrapping it in a newtype:

newtype Mirror b a = Mirrored (Either a b)

instance Functor (Mirror e) where
    fmap _ (Mirrored (Right a)) = Mirrored $ Right a
    fmap f (Mirrored (Left b)) = Mirrored $ Left (f b)

Wrapping with newtype is also the standard way to create multiple instances for a single type, such as Sum and Product being instances of Monoid for numeric types. Otherwise, you can only have one instance per type.

Additionally, depending on what it is you want to do, another option is to ignore Functor and define your own type class like this:

class Bifunctor f where
    bimap :: (a -> c) -> (b -> d) -> f a b -> f c d

instance Bifunctor Either where
    bimap f _ (Left a)  = Left  $ f a
    bimap _ g (Right b) = Right $ g b

instance Bifunctor (,) where
    bimap f g (a, b) = (f a, g b)

Obviously, that class is twice as much fun as a regular Functor. Of course, you can't make a Monad instance out of that very easily.

这篇关于操作参数的顺序来构造函数类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆