1

我的意思是,不是像这样简单的东西(从这里):

strike :: StateT Game IO ()
strike = do
    lift $ putStrLn "*shink*"
    boss.health -= 10

但是像使用镜头映射类型从Linear. 我将如何用镜头来表达这一点:

vecMod :: (Integral a) => V2 a -> V2 a -> V2 a
vecMod (V2 x1 y1) (V2 x2 y2) = V2 (x1 `mod` x2) (y1 `mod` y2)

另一个例子:我当前的代码充满了这样的小表达式:

isAt :: Thing -> Position -> Game Bool
isAt thing pos = do
  b <- use board
  return $ elem thing (b ! pos)

(板在哪里Array (V2 Int)

我猜是(和lens)有一种更规范的方式来表达这一点。

一般来说:我如何找出镜头能够做什么,不能做什么以及它是如何完成的?

4

1 回答 1

1

第一个 vecMod 很容易简化:

import Control.Applicative

data V2 a = V2 a a  deriving Show

instance Functor V2 where
    fmap f (V2 x y) = V2 (f x) (f y)

instance Applicative V2 where
    pure x = V2 x x
    (V2 f g) <*> (V2 x y) = V2 (f x) (g y)

vecMod1,vecMod2 :: (Integral a) => V2 a -> V2 a -> V2 a
vecMod1 (V2 x1 y1) (V2 x2 y2) = V2 (x1 `mod` x2) (y1 `mod` y2)
vecMod2 = liftA2 mod

您可以看到 liftA2 有效,因为我以明显的方式使 V2 适用。

第二个已经很简洁了。如果您发布此类片段的集合,我们可以帮助抽象一些内容。

于 2013-09-22T18:17:52.943 回答