How does `lens` work?

旧时模样 提交于 2019-12-24 12:51:55

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!