我正在努力完成这个tutorial。如教程中所述,我复制了一些代码,用于表示functor composition
和identity functor
:
{-# LANGUAGE FlexibleContexts #-}
module Test where
newtype FComp f g a = C { unC :: f (g a) }
instance (Show (f (g a))) => Show (FComp f g a) where
show (C x) = "FComp " ++ show x
instance (Functor f, Functor g) => Functor (FComp f g) where
fmap h (C x) = C (fmap (fmap h) x)
newtype Id a = Identity { unId :: a } deriving Show
instance Functor Id where
fmap f x = Identity (f (unId x))
现在,这是本教程关于identity functor
:
Composition with the identity functor in the same category is as expected.
F∘IdB = F
IdA∘F = F
我坚持的是尝试按照上面代码中的FComp
所代表的仿函数构成来考虑它。以下示例:
$ let a = C (Identity (Just (5::Int)))
$ :t a
a :: FComp Id Maybe Int
$ let b = C (Just (Identity (5::Int)))
$ :t b
b :: FComp Maybe Id Int
我想不出一种方法来断言上面例子中表示的a
和b
类型是相同的。我将非常感谢如何根据identity functor
来考虑functor composition
。
答案 0 :(得分:9)
与Haskell应用的类别理论中的许多等式一样, F ∘Id B ≡Id A ∘ F ≡ F 应该只是作为等价读取。 FComp Id Maybe Int
与类型检查器的FComp Maybe Id Int
非常不一样;但是你可以轻松写出
idFunctorIso :: Functor f => FComp f Id a -> f a
idFunctorIso (C fIdca) = fmap unId fIdca
idFunctorIso' :: Functor f => f a -> FComp f Id a
idFunctorIso' fa = C $ fmap Identity fIdc
这意味着两种类型都包含相同的信息 1 。这就是我们所说的他们是同构的意思。
1 自idFunctorIso' . idFunctorIso ≡ id
以来,fmap id ≡ id
的任何方向都没有丢失任何信息(以下是函数法unC
,以及unId
和{{{1}} {1}}是newtype构造函数的简单反转。)