【发布时间】:2015-05-08 23:04:22
【问题描述】:
我想知道是否有一个Applicative 可以跟踪发生了多少应用操作。我尝试按如下方式实现它:
import Control.Applicative
main :: IO ()
main = print $ run 1 $ (,,,) <$> FromInt id <*> FromInt id <*> FromInt id <*> FromInt id
data FromInt a = FromInt (Int -> a)
run :: Int -> FromInt a -> a
run i (FromInt f) = f i
instance Functor FromInt where
fmap g (FromInt f) = FromInt (g . f)
instance Applicative FromInt where
pure a = FromInt (const a)
FromInt f <*> FromInt g = FromInt (\i -> f i (g (i + 1)))
但是,这当然行不通。如果我们在文件上调用 runhaskell,我们会得到:
(1,2,2,2)
而我想要的是这样的:
(1,2,3,4)
我见过人们通过将增量需求推送到实际数据中来实现这种效果(这就是 yesod-forms 的 formlet 样式实现方式)。这或多或少使用了State 的变体,如果人们不使用特定的辅助函数(我认为yesod 称为mhelper),它允许人们打破假定的不变量。我想知道增量是否可以像我尝试做的那样被拉入应用实例。这样就不可能违反这个特定的不变量。
【问题讨论】:
-
我不相信这是可能的,因为应用操作不能依赖于先前的结果。为此,我认为您必须有一个 monad 才能获得所需的输出。
-
你不需要单子。
State的应用实例工作正常,但我希望有更好的方法。
标签: haskell applicative