标签: haskell-lens

你如何使用镜头库编写依赖于其他镜头的复杂镜头?

目前,我有一个WorkLog类型,有开始和结束日期.我还要添加一个持续时间镜头,它将从开始和结束日期派生.它应该是只读的,或者如果它的值被改变就改变结束日期(我想知道如何实现这两个版本,即使我只使用一个).

这是我的代码.基本上,如果你可以实现workLogDurationROworkLogDurationRW函数来获得主要传递的所有测试,那将回答我的问题.

{-# 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 …
Run Code Online (Sandbox Code Playgroud)

haskell haskell-lens

3
推荐指数
1
解决办法
176
查看次数

教程中的简单 Haskell 镜头违反了镜头定律

我正在阅读本教程:

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
Run Code Online (Sandbox Code Playgroud)

现在跟随博客文章,这里有一些常见的镜头计算:

*Main> …
Run Code Online (Sandbox Code Playgroud)

haskell haskell-lens

3
推荐指数
1
解决办法
214
查看次数

Haskell 使用一级透镜来创建复杂透镜

假设我有一个包含两个字段的对象:

data Example = Example { _position :: Int
                       , _storage  :: [Int]}
Run Code Online (Sandbox Code Playgroud)

如何构建聚焦于position内部元素的镜头storage

另外,是否可以将position通过镜头修改的值限制在基于尺寸的范围内storage

似乎可以以某种方式使用旁边Example,因为它与元组同构,但我无法理解这样做的方法。

我不知道如何表达这个问题,所以我无法找到很多相关信息。

haskell haskell-lens

3
推荐指数
1
解决办法
413
查看次数

如果模式与`Maybe a`结果匹配

以下代码说明了我的意图.我想模式匹配,如果没有结果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"
-- …
Run Code Online (Sandbox Code Playgroud)

haskell haskell-lens

3
推荐指数
1
解决办法
240
查看次数

如何镜头到一个多态函数的记录字段?

我刚刚安装了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
Run Code Online (Sandbox Code Playgroud)

错误是No Instance for (Contravariant Identity) arising from use of 'func'.

我看了一下Contravariant,我很确定自从我做这个实例是不可能的

class Contravariant f where
  contramap :: (a -> b) -> f b -> f a
Run Code Online (Sandbox Code Playgroud)

即如果f = \x -> x …

haskell haskell-lens

3
推荐指数
1
解决办法
129
查看次数

是不是可以让复合镜片束缚?

我无法通过帮助类型检查器来理解以下是否可行,或者完全不可能.设置略微任意的,我只是需要与镜头,这里所说的一些嵌套的数据类型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 …
Run Code Online (Sandbox Code Playgroud)

haskell unification functor haskell-lens

3
推荐指数
1
解决办法
83
查看次数

如何为特定类型实现类似Getter的镜头?

给定一般Getter类型

type Getter s a = forall f. (Contravariant f, Functor f) => (a -> f a) -> s -> f s
Run Code Online (Sandbox Code Playgroud)

我将如何为一对元组实现一个吸气剂?我想上面的类型代表了部分应用的功能,而缺少的部分正是让我感到困惑的地方。

除此之外,我不了解逆约束。可能是为了使镜头类型更像,但功能还不够吗?

haskell lenses haskell-lens

3
推荐指数
1
解决办法
65
查看次数

使用镜头测试地图成员资格

使用镜头检查有状态地图是否有键的惯用方法是什么?这是我目前的尝试:

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!"
Run Code Online (Sandbox Code Playgroud)

这有效,但该to isJust部分感觉有点笨重......

haskell haskell-lens

3
推荐指数
1
解决办法
100
查看次数

带镜头的增量后缀

如何编写一个基于镜头的函数,增加数字后缀(如果存在)并在没有这样的后缀时保持字符串不变?

"aaa1" -> "aaa2"
"aaa_123" -> "aaa_124"
"" -> ""
"aaa" -> "aaa"
"123a" -> "123a"
"3a5" -> "3a6"
Run Code Online (Sandbox Code Playgroud)

我觉得我可能首先需要一些棱镜,但不知道是哪一个(suffixed没有函数作为参数,而是标量)。

haskell haskell-lens

3
推荐指数
1
解决办法
91
查看次数

Brick 未导出 下一步或继续

我正在尝试使用 Haskell 和 Brick 包为基本应用程序构建 CLI 界面。在我见过的所有示例(包括文档)中,函数handleEvent具有以下类型签名,以便告诉 Brick 在状态更新后继续或停止执行:

AppState -> BrickEvent n e -> EventM n (Next AppState)
Run Code Online (Sandbox Code Playgroud)

然而,对我来说,我的编译器说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
                _ -> …
Run Code Online (Sandbox Code Playgroud)

haskell state-monad haskell-lens haskell-brick

3
推荐指数
1
解决办法
360
查看次数