问题
I mean, not the simple stuff like this (from here):
strike :: StateT Game IO ()
strike = do
lift $ putStrLn "*shink*"
boss.health -= 10
But things like using lens to map over types from Linear
. How would I express this in terms of lens:
vecMod :: (Integral a) => V2 a -> V2 a -> V2 a
vecMod (V2 x1 y1) (V2 x2 y2) = V2 (x1 `mod` x2) (y1 `mod` y2)
Another example: my current code is full of small expressions like this:
isAt :: Thing -> Position -> Game Bool
isAt thing pos = do
b <- use board
return $ elem thing (b ! pos)
(where board is Array (V2 Int)
)
I guess is that there (with lens
) there is a more canonical way to express this.
In general: how do I find out what lens is able to do, what not and how it is done?
回答1:
The first vecMod is easy to simplify:
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
You can see liftA2 works because I made V2 applicative in the obvious way.
The second is already quite terse. If you post a collections of such snippets we could help abstract a few things.
来源:https://stackoverflow.com/questions/18947136/how-does-lens-work