我在 Haskell 中定义了一个 monadic 计数器,我正试图将其转换为 Scala,但到目前为止失败得很惨。简而言之,问题是将计数器实现为状态 monad,它从环境中读取计数器增量常量,并记录计数器的历史记录(其值序列)。
我的一个朋友改进了我的解决方案,并提出了这个简单的解决方案:
newtype Counter = Counter Int deriving (Eq)
instance Show Counter where
show (Counter i) = show i
incWith :: MonadState Counter m => Int -> m ()
incWith n = let incCounter n' (Counter i) = Counter $ i + n'
in modify (incCounter n)
inc :: (MonadReader Int m, MonadState Counter m, MonadWriter [Counter] m) => m ()
inc = ask >>= incWith >> get >>= tell . (:[])
compute :: (MonadReader Int m, MonadState Counter m, MonadWriter [Counter] m) => m ()
compute =
local (const 3) $ do
inc
inc
inc
local (const 5) $ do
inc
inc
我尝试将其编码为 Scala + (Cats | ScalaZ),但没有成功。Cats的最新稳定版本缺少lift
. WriterT
并且ReaderWriterState
在Scalaz
几个小时内我无法弄清楚如何使用该local
方法。而这仅仅是开始......
这个 Haskell 解决方案如何以简单而优雅的方式翻译?(在语言允许的范围内)。
边注:
我仍在试图弄清楚为什么我需要花费这么多时间将简单的解决方案从 Haskell 转换为 Scala + FP 库(Cats、Scalaz)。在 Haskell 中查找每个类型类的实例和可用函数是一件轻而易举的事,在使用 IntelliJ、GitHub 和 StackOverflow 的 Scala 中,这需要我几天的时间。所以我想知道我做错了什么,我该如何改善这种情况。