這是怎麼講的是類型構造像[]
和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)
事實上,哈斯克爾平臺自帶的,讓你一個Compose
類型,這是否「免費」的模塊Data.Functor.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的全部功能的情況。
你有沒有試過在ghci中自己編寫fmap?即':t fmap。 fmap' – Squidly
@MrBones感謝您的提示!對於那些沒有ghci訪問權限的人來說,輸出是'::(Functor f1,Functor f)=>(a - > b) - > f(f1 a) - > f(f1 b)' – akbiggs