Identity Functor究竟做了什么?

时间:2015-04-22 16:25:43

标签: haskell

这可能是微不足道的,但我不明白以下是什么意思。

instance Functor Identity where
    fmap     = coerce

所以,我可以尝试定义类似的东西:

Prelude Control.Lens Data.Functor.Identity> :t fmap
fmap :: Functor f => (a -> b) -> f a -> f b
Prelude Control.Lens Data.Functor.Identity> let z f g = coerce f g
Prelude Control.Lens Data.Functor.Identity> :t z
z :: Contravariant ((->) t) => (t -> a) -> t -> b

但是,用简单的术语来表达什么意思?

2 个答案:

答案 0 :(得分:7)

class DeadlockTest extends TestKit(ActorSystem()) with FunSuiteLike { test("deadlock attempt") { val b = TestProbe() val a = TestActorRef(new Actor { override def preStart() = b.ref ! "pre" def receive = { case msg => sender ! msg context.stop(self) } }) b.watch(a) b.send(a, "foo") b.expectMsg("pre") b.expectMsg("foo") b.expectTerminated(a) b.unwatch(a) } } 的使用在GHC 7.10中是新的,并且是为了提高效率而完成的。 “真正的”定义是

coerce

fmap :: (a -> b) -> (Identity a -> Identity b) fmap f (Identity a) = Identity (f a) 构造函数的包装/解包应该在编译时进行优化,但似乎Identity开发人员有理由确保使用{{1}不会降低性能}。

我们可以使用base的原因是coercecoerce同构(同一),因此我们可以强制Identity aa恰好是专门针对a -> b的{​​{1}}的定义!

答案 1 :(得分:5)

您在哪里找到Identity的仿函数实例?这是我在Data.Functor.Identity中找到的那个:

newtype Identity a = Identity { runIdentity :: a }

instance Functor Identity where
  fmap f m = Identity (f (runIdentity m))

但至于它做了什么......它绝对没有,而且这是故意的。 fmap f (Idendity x)Idendity (f x)相同。它只是将函数应用于它包含的值。

为什么你想要一个没有做任何事情的算子?如果你的函数需要一个仿函数,但你只有一个常规的非仿函数值,你可以将你的值包装在Identity中并传入它并且它会表现正常。它基本上只是为了满足类型检测器的一层包装。