代码之家  ›  专栏  ›  技术社区  ›  bbarker

在lens中自动生成Has类型类的文档在哪里?

  •  1
  • bbarker  · 技术社区  · 7 年前

    我在看倒数第二个例子 blog post (同时 here lens contents 或者 lens tutorial makeLenses ,或者在这种情况下, makeLensesWith ).

    以下是复制的代码:

    #!/usr/bin/env stack
    -- stack --resolver lts-8.12 script
    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE TemplateHaskell #-}
    {-# LANGUAGE MultiParamTypeClasses #-}
    {-# LANGUAGE FunctionalDependencies #-}
    import Control.Concurrent.Async.Lifted.Safe
    import Control.Monad.Reader
    import Control.Concurrent.STM
    import Say
    import Control.Lens
    import Prelude hiding (log)
    
    data Env = Env
      { envLog :: !(String -> IO ())
      , envBalance :: !(TVar Int)
      }
    
    makeLensesWith camelCaseFields ''Env
    
    modify :: (MonadReader env m, HasBalance env (TVar Int), MonadIO m)
           => (Int -> Int)
           -> m ()
    modify f = do
      env <- ask
      liftIO $ atomically $ modifyTVar' (env^.balance) f
    
    logSomething :: (MonadReader env m, HasLog env (String -> IO ()), MonadIO m)
                 => String
                 -> m ()
    logSomething msg = do
      env <- ask
      liftIO $ (env^.log) msg
    
    main :: IO ()
    main = do
      ref <- newTVarIO 4
      let env = Env
            { envLog = sayString
            , envBalance = ref
            }
      runReaderT
        (concurrently
          (modify (+ 1))
          (logSomething "Increasing account balance"))
        env
      balance <- readTVarIO ref
      sayString $ "Final balance: " ++ show balance
    
    0 回复  |  直到 7 年前
        1
  •  2
  •   bergey    7 年前

    Field 是这个词吗 lens 用于描述每个命名字段一个类的模式,允许具有相同字段名但(可选)不同类型的多个记录。所以呢 camelCaseFields makeFieldOptics , defaultFieldRules 所有人都以他们的名义说他们将产生这些 HasFoo 课程,以通常的简洁风格 透镜 .

    makeClassy 生成名为 Has* ,但以数据类型命名,而不是记录字段,并且不遵循不同的模式。

    上面的代码生成以下代码(用 -ddump-splices

        makeLensesWith camelCaseFields ''Env
      ======>
        class HasBalance s a | s -> a where
          balance :: Lens' s a
        instance HasBalance Env (TVar Int) where
          {-# INLINE balance #-}
          balance f_a4eTr (Env x1_a4eTs x2_a4eTt)
            = (fmap (\ y1_a4eTu -> (Env x1_a4eTs) y1_a4eTu)) (f_a4eTr x2_a4eTt)
        class HasLog s a | s -> a where
          log :: Lens' s a
        instance HasLog Env (String -> IO ()) where
          {-# INLINE log #-}
          log f_a4eTx (Env x1_a4eTy x2_a4eTz)
            = (fmap (\ y1_a4eTA -> (Env y1_a4eTA) x2_a4eTz)) (f_a4eTx x1_a4eTy)
    
    推荐文章