【发布时间】:2019-09-22 23:54:43
【问题描述】:
我正在阅读haskellbook 的第 25 章(组合类型),并希望更全面地理解应用组合
作者提供了一个类型来体现类型组合:
newtype Compose f g a =
Compose { getCompose :: f (g a) }
deriving (Eq, Show)
并为此类型提供函子实例:
instance (Functor f, Functor g) =>
Functor (Compose f g) where
fmap f (Compose fga) =
Compose $ (fmap . fmap) f fga
但 Applicative 实例留给读者作为练习:
instance (Applicative f, Applicative g) =>
Applicative (Compose f g) where
-- pure :: a -> Compose f g a
pure = Compose . pure . pure
-- (<*>) :: Compose f g (a -> b)
-- -> Compose f g a
-- -> Compose f g b
Compose fgf <*> Compose fgx = undefined
我可以作弊并在网上查找答案...Data.Functor.Compose 的来源提供了应用实例定义:
Compose f <*> Compose x = Compose ((<*>) <$> f <*> x)
但我无法理解这里发生了什么。根据类型签名,f 和x 都包裹在两层应用结构中。不过,我似乎遇到的障碍是了解这个位发生了什么:(<*>) <$> f。我可能会有后续问题,但它们可能取决于如何评估该表达式。是说“fmap <*> over f”还是“将<$> 应用到 f”?
请帮助您直观地了解这里发生的事情。
谢谢! :)
【问题讨论】:
-
Compose fgh <*> Compose fgx = Compose ((<*>) <$> fgh <*> fgx) = Compose (liftA2 (<*>) fgh fgx)和liftA2 (<*>) fgh fgx ::~ f {gh <*> gx} :: f (g {h x})(伪代码,将{ }读作“类型”)。
标签: haskell applicative function-composition