【发布时间】:2019-12-14 11:17:01
【问题描述】:
我有以下类型:
newtype Rep f a = Rep { runRep :: String -> f (String, a) }
类型 Rep f a 是一个有状态的计算,它以一个 String 作为初始状态并产生一个 (String, a) 作为计算的结果。计算的结果被包裹在函子 f 中。
Rep 的应用实例如下:
instance Monad f => Applicative (Rep f) where
pure x = Rep $ \s -> pure (s, x)
Rep f <*> Rep x = Rep $ \s -> do
(s',rf) <- f s
(s'',rx) <- x s'
return (s'', rf rx)
Rep 的 monad 实例如下:
instance Monad f => Monad (Rep f) where
return x = pure x
Rep a >>= f = Rep $ \s -> do
(s', ya) <- a s
let (Rep f') = f ya
(s'', yf) <- f' s'
pure (s'', yf)
我有以下数据类型和功能:
data TD = Empty | Fol TD TD | Letters [Char]
data Res = Nil | Character Char | Cop Res Res | Special [Res]
findmatch (Fol a b) = do
ra <- findmatch a
rb <- findmatch b
pure (Cop ra rb)
findmatch (Fol a b) = Cop <$> findmatch a <*> findmatch b
我无法理解涉及<$> 的findmatch 的第二个定义是如何工作的。我知道<$> 有以下类型声明:
(<$>) :: (Functor f) => (a -> b) -> f a -> f b
f <$> x = fmap f x
<$> 的第一个参数应该是一个函数,而第二个参数应该是一个封装在仿函数中的值。 findmatch 的结果是一个包裹在函子中的值,但是 Cop 在这种情况下是一个函数吗?我知道Cop 是一个值构造函数,它接受两个Res 类型的参数。如果将一个 Res 类型的参数传递给 Cop,我认为这是在 Cop <$> findmatch a 中发生的,这将返回另一个函数,该函数采用 Res 类型的值。但是,我不确定由部分应用程序产生的第二个函数返回的结果类型是什么。
感谢任何见解。
【问题讨论】:
-
您需要查看
Applicative的Rep实例以了解为什么两者是等价的。更简短的回答是对findmatch的两次递归调用之间没有数据依赖关系,因此Monad实例不必要地强制一个在另一个之前运行。Applicative实例没有。
标签: haskell functional-programming