目前,我有一个WorkLog类型,有开始和结束日期.我还要添加一个持续时间镜头,它将从开始和结束日期派生.它应该是只读的,或者如果它的值被改变就改变结束日期(我想知道如何实现这两个版本,即使我只使用一个).
这是我的代码.基本上,如果你可以实现workLogDurationRO和workLogDurationRW函数来获得主要传递的所有测试,那将回答我的问题.
{-# LANGUAGE TemplateHaskell #-}
module Main where
import Control.Lens
-- Keep times simple for this example
newtype TimeStamp = TimeStamp Int deriving (Show, Eq)
newtype TimeDifference = TimeDifference Int deriving (Show, Eq)
(-.-) :: TimeStamp -> TimeStamp -> TimeDifference
(TimeStamp a) -.- (TimeStamp b) = TimeDifference (a - b)
data WorkLog = WorkLog {
  _workLogDescription :: String
  , _workLogStartTime :: TimeStamp
  , _workLogEndTime :: TimeStamp
  }
makeLenses ''WorkLog
-- | Just return …我正在阅读本教程:
http://blog.jakubarnold.cz/2014/08/06/lens-tutorial-stab-traversal-part-2.html
我的代码如下所示:
import Control.Applicative
import Data.Traversable
import Control.Lens
data User = User String [Post] deriving Show
data Post = Post String deriving Show
posts :: Lens' User [Post]
posts f (User n p) = fmap (User n) (f p)
users :: [User]
users = [User "john" [Post "hello", Post "world"], User "bob" [Post "foobar"]]
tp :: (Traversable t, Applicative f) => ([Post] -> f [Post]) -> t User -> f (t User)
tp = traverse . posts
现在跟随博客文章,这里有一些常见的镜头计算:
*Main> …假设我有一个包含两个字段的对象:
data Example = Example { _position :: Int
                       , _storage  :: [Int]}
如何构建聚焦于position内部元素的镜头storage?
另外,是否可以将position通过镜头修改的值限制在基于尺寸的范围内storage?
似乎可以以某种方式使用旁边Example,因为它与元组同构,但我无法理解这样做的方法。
我不知道如何表达这个问题,所以我无法找到很多相关信息。
以下代码说明了我的意图.我想模式匹配,如果没有结果Nothing,如果匹配结果是Just something
data MyData = 
      A Int
    | B String
    | C
ifA (A i) = Just i 
ifA _     = Nothing
ifB (B str) = Just str
ifB _     = Nothing
ifC C = Just () 
ifC _ = Nothing 
mbMult3 i = Just (i*3)
concWorld str = Just (str ++ "World")
example1 v = ifA v >>= mbMult3
example2 v = ifB v >>= concWorld
-- example2 (B "Hello ,") == Just "Hello, World"
-- …我刚刚安装了lens库,因此我可以轻松地set在嵌套数据结构中.但是,我遇到了一个问题.这是一个演示我的问题的最小例子
以下代码无法编译:
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens    
data MyRecord = MyRecord 
  { _func :: forall . a -> a
  }
makeLenses ''MyRecord
changeMyRecord :: MyRecord -> MyRecord
changeMyRecord r = r & func .~ id
错误是No Instance for (Contravariant Identity) arising from use of 'func'.
我看了一下Contravariant,我很确定自从我做这个实例是不可能的
class Contravariant f where
  contramap :: (a -> b) -> f b -> f a
即如果f = \x -> x …
我无法通过帮助类型检查器来理解以下是否可行,或者完全不可能.设置略微任意的,我只是需要与镜头,这里所说的一些嵌套的数据类型A,B,C.
我的问题是我可以使用复合镜头,(bLens . a)如果我立即调用类似的东西view,但如果我尝试让它绑定并给它一个名字,我会得到错误信息.
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MonoLocalBinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
module Debug where
import Control.Eff
import Control.Eff.Reader.Strict
import Control.Lens
data A = A
data B = B
  { _a :: A
  }
makeLenses ''B
data C = C
  { _b :: B
  }
makeLenses ''C
askLensed :: ( Member (Reader r) e ) => Lens' r …给定一般Getter类型
type Getter s a = forall f. (Contravariant f, Functor f) => (a -> f a) -> s -> f s
我将如何为一对元组实现一个吸气剂?我想上面的类型代表了部分应用的功能,而缺少的部分正是让我感到困惑的地方。
除此之外,我不了解逆约束。可能是为了使镜头类型更像,但功能还不够吗?
使用镜头检查有状态地图是否有键的惯用方法是什么?这是我目前的尝试:
module Foo where
import Control.Lens
import Data.Map
import Control.Monad.State
import Data.Maybe (isJust)
check :: Int -> StateT (Map Int Int) IO ()
check k = do
  present <- use $ at k.to isJust
  unless present $ lift $ putStrLn "Not present!"
这有效,但该to isJust部分感觉有点笨重......
如何编写一个基于镜头的函数,增加数字后缀(如果存在)并在没有这样的后缀时保持字符串不变?
"aaa1" -> "aaa2"
"aaa_123" -> "aaa_124"
"" -> ""
"aaa" -> "aaa"
"123a" -> "123a"
"3a5" -> "3a6"
我觉得我可能首先需要一些棱镜,但不知道是哪一个(suffixed没有函数作为参数,而是标量)。
我正在尝试使用 Haskell 和 Brick 包为基本应用程序构建 CLI 界面。在我见过的所有示例(包括文档)中,函数handleEvent具有以下类型签名,以便告诉 Brick 在状态更新后继续或停止执行:
AppState -> BrickEvent n e -> EventM n (Next AppState)
然而,对我来说,我的编译器说Next找不到(我也不能手动从它应该位于的包中导出它Brick.Main)。下面使用的函数也是如此continue。
最小可重现问题:
主要.hs:
module Main where
import Brick.Main
import Brick.Types
import Graphics.Vty.Input.Events
data AppState = AppState deriving (Show, Eq)
handleEvent :: AppState -> BrickEvent n e -> EventM n (Next AppState)
handleEvent s e =
    case e of
        VtyEvent vtye ->
            case vtye of
                EvKey (KChar 'q') [] -> halt s
                _ -> …