Tho*_*ing 21 math haskell functor
"类似的论点也表明,满足第一定律的任何Functor实例(fmap id = id)也会自动满足第二定律.实际上,这意味着只需要检查第一定律(通常通过非常简单的归纳法)确保Functor实例有效."
如果是这种情况,为什么我们甚至提到第二个仿函法?
Law 1: fmap id = id
Law 2: fmap (g . h) = (fmap g) . (fmap h)
Run Code Online (Sandbox Code Playgroud)
Tom*_*ett 20
虽然我无法提供证据,但我相信这说的是,由于参数性,只要第一定律成立,类型系统就会执行第二定律.指定这两个规则的原因是,在更一般的数学设置中,您可能有一些类别C,其中完全可以定义从C到其自身的"映射" (即Obj(C )和Hom上的一对内部函数(C )分别)遵守第一条规则但不遵守第二条规则,因此不构成仿函数.
请记住,FunctorHaskell中的s是Hask类别的endofunctor,甚至在Haskell 上也不能用数学上被认为是Haskell上的endofunctor的所有内容...参数多态的约束排除了能够指定一个不行为的函子统一地映射它的所有对象(类型).
基于这个主题,普遍的共识似乎是第二个定律从Haskell Functor实例的第一个定律开始.爱德华凯梅特说,
给定
fmap id = id,fmap (f . g) = fmap f . fmap g遵循fmap的自由定理.这篇文章在很长一段时间内作为一篇文章发表在一篇文章中,但我忘了在哪里.
ham*_*mar 13
使用seq,我们可以编写一个满足第一个规则但不满足第二个规则的实例.
data Foo a = Foo a
deriving Show
instance Functor Foo where
fmap f (Foo x) = f `seq` Foo (f x)
Run Code Online (Sandbox Code Playgroud)
我们可以验证这符合第一定律:
fmap id (Foo x)
= id `seq` Foo (id x)
= Foo (id x)
= Foo x
Run Code Online (Sandbox Code Playgroud)
然而,它打破了第二定律:
> fmap (const 42 . undefined) $ Foo 3
Foo 42
> fmap (const 42) . fmap undefined $ Foo 3
*** Exception: Prelude.undefined
Run Code Online (Sandbox Code Playgroud)
也就是说,我们通常会忽略这种病态病例.