这里所说的是类型构造函数的组合,例如[]
and 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)
-- Now we can derive Functor and Applicative instances based on those of Compose
deriving (Functor, Applicative)
请注意,两个Applicative
s 的组合也是一个Applicative
. 因此,因为[]
和Maybe
是Applicative
s,所以Compose [] Maybe
和ListOfMaybe
。组合Applicative
s 是一种非常巧妙的技术,如今它正在慢慢变得越来越普遍,作为 monad 转换器的替代方案,用于在不需要 monad 的全部功能的情况下。