这里谈论的是类别构造函数的组合,例如[]
和Maybe
,而不是函数的组合,如fmap
。因此,例如,有两种方式可以组合[]
和Maybe
:
newtype ListOfMabye a = ListOfMaybe [Maybe a]
newtype MaybeOfList a = MaybeOfList (Maybe [a])
两个 Functors
的组合是一个 Functor
的说法意味着有一种公式化的方式来为这些类型编写 Functor
实例:
instance Functor ListOfMaybe where
fmap f (ListOfMaybe x) = ListOfMaybe (fmap (fmap f) x)
instance Functor MaybeOfList where
fmap f (MaybeOfList x) = MaybeOfList (fmap (fmap f) x)
事实上,Haskell平台附带了模块Data.Functor.Compose
,它提供了一个Compose
类型,可以免费完成这个操作:
import Data.Functor.Compose
newtype Compose f g a = Compose { getCompose :: f (g a) }
instance (Functor f, Functor g) => Functor (Compose f g) where
fmap f (Compose x) = Compose (fmap (fmap f) x)
Compose
特别适用于使用 GeneralizedNewtypeDeriving
扩展:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype ListOfMaybe a = ListOfMaybe (Compose [] Maybe a)
deriving (Functor, Applicative)
请注意,两个Applicative
的组合也是一个Applicative
。因此,既然[]
和Maybe
都是Applicative
,那么Compose [] Maybe
和ListOfMaybe
也是Applicative
。组合Applicative
是一种非常巧妙的技术,这种技术正在逐渐变得更加常见,作为单子变换器的替代方案,用于在不需要单子的全部能力的情况下。
:t fmap . fmap
。 - Squidly::(Functor f1,Functor f)=>(a-> b)-> f(f1 a)-> f(f1 b)
。 - akbiggs