我的意思是,不是像这样简单的东西(来自here):
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
)有更规范的表达方式。
一般情况下:我如何找出能够做什么镜头,做什么不做以及如何做?
答案 0 :(得分: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适用。
第二个已经非常简洁了。如果您发布这些片段的集合,我们可以帮助抽象一些事情。