标签: haskell-lens

Haskell Control.Lens遍历棱镜

我有一个深度嵌套的数据结构,我正在使用Control.Lens.*来简化在状态monad中访问它的值.

请考虑以下事项:

data Config = Config { _foo :: Maybe Int
                     , _bar :: Int
                     }

$(makeLenses ''Config)
Run Code Online (Sandbox Code Playgroud)

如何在"可爱"上"操作"地操作?我想写一个惯用的吸气剂:

config = Config (Just 1) 0
config^.foo.to fmap (+1) == Just 2
Run Code Online (Sandbox Code Playgroud)

更好的是,当Config嵌套得更深时,我们将如何处理这种情况?

data Config = { _foo :: Maybe Foo }
data Foo = Foo { _bar :: Bar }
data Bar = Bar Int
$(makeLenses ''Bar)
$(makeLenses ''Foo)
Run Code Online (Sandbox Code Playgroud)

我们可以使用访问器foo和bar来返回修改后的Bar吗?

haskell lenses haskell-lens

4
推荐指数
1
解决办法
2073
查看次数

如何使用镜头语法检查地图是否有键?

如何使用镜头语法检查地图是否有键?

import qualified Map as Map

let x = Map.member "bla" m
Run Code Online (Sandbox Code Playgroud)

如何使用镜头来写这个?

haskell haskell-lens

4
推荐指数
1
解决办法
621
查看次数

如何使用 Lenses 用 `concat` 表达 `mapM` 以连接 IO 操作的结果?

我试图找出一种方法,如何以允许以下方式结合traverseOf使用>>=

TLDR;一个简单的 Haskell 示例就是这样,但是在数据结构的深处使用镜头。

?> fmap concat $ mapM ((return :: a -> IO a) . const ["he", "he"]) ["foo", "bar", "baz"]
["he","he","he","he","he","he"]
Run Code Online (Sandbox Code Playgroud)

这是一个带有示例的冗长解释

data Foo = Foo [Bar] deriving Show
data Bar = Baz | Qux Int [String] deriving Show

makePrisms ''Foo
makePrisms ''Bar

items :: [Foo]
items = [Foo [Baz], Foo [Qux 1 ["hello", "world"], Baz]]

-- Simple replacement with a constant value
constReplace :: [Foo]
constReplace = over (traverse._Foo.traverse._Qux._2.traverse) (const "hehe") items
-- …
Run Code Online (Sandbox Code Playgroud)

haskell lenses haskell-lens

4
推荐指数
1
解决办法
560
查看次数

如何使用带镜头的IORef?

想知道如何最好地将Control.Lens包与IORefs 结合起来.具体来说,我希望能够使用atomicModifyIORef镜头,以便我可以提供类型的功能,a -> (a, b)并从操作返回一个值.代码段:

let inc x = (x+1, x)
ior <- newIORef ((1, 1) :: (Int, Int))
thisShouldBe1 <- ior & atomicModifyIORef ?? _1 inc -- this is the bit I'm stuck on
Run Code Online (Sandbox Code Playgroud)

haskell atomic haskell-lens ioref

4
推荐指数
1
解决办法
430
查看次数

用镜头刺伤获得价值

我想编写一个函数,在Lens stab的帮助下将函数(a - > b)转换为函数(s - > t)(编辑:我意识到这个函数已经存在Setter s t a b并且被称为over或者%~,但是它没有回答下面使用镜头获取值的问题).看起来很简单,但我遇到了一个令人困惑的类型错误.要创建一个更小的示例,请考虑以下函数,它只返回镜头从第二个参数中提取的值:

f :: Lens s t a b -> s -> a
f l s = s ^. l
Run Code Online (Sandbox Code Playgroud)

这不编译.在^的第二个参数中有2个错误.(即l):

  • 无法将类型't'与's'匹配
  • 无法将类型'a'与'b'匹配

但是,以下编译:

f :: Getter s a -> s -> a
f l s = s ^. l
Run Code Online (Sandbox Code Playgroud)

然后,我意识到在镜头类型层次结构中,Lens和Getter之间的箭头指定s = t,a = b.有没有办法使用常规从Lens s t a b类型a的值中获取类型的值s

haskell lenses haskell-lens

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

用镜头索引遍历

我有一个镜头指向一个 json 文档,例如

doc ^? ((key "body").values)
Run Code Online (Sandbox Code Playgroud)

现在我想用键“key”对 body 中的值进行索引,因为 json 看起来像

{"body": [{"key": 23, "data": [{"foo": 1}, {"foo": 2}]}]}
Run Code Online (Sandbox Code Playgroud)

所以我正在寻找一些可以让我通过另一个镜头进行索引的东西:

doc ^? key "body" . values
      . indexWith (key "key")
      . key "data" . values
      . key "foo" . withIndex
Run Code Online (Sandbox Code Playgroud)

应该返回

[(23, 1), (23, 2)]
Run Code Online (Sandbox Code Playgroud)

MVCE:

#!/usr/bin/env stack
-- stack --resolver lts-11.7 script
-- --package lens
-- --package text
-- --package lens-aeson
{-# LANGUAGE OverloadedStrings #-}
import Control.Lens
import Data.Aeson.Lens
import Data.Text

doc :: Text
doc = …
Run Code Online (Sandbox Code Playgroud)

haskell haskell-lens

4
推荐指数
1
解决办法
671
查看次数

Haskell Lens:可能的棱镜

我有这些镜头:

getB :: Lens' A (Maybe B) 

getC :: Prism' B C
Run Code Online (Sandbox Code Playgroud)

如何Maybe C从A中提取a ?我能找到的最好的:

case A ^. getB of
    Just b -> b ^? getC
    Nothing -> Nothing
Run Code Online (Sandbox Code Playgroud)

还有更优雅的吗?

haskell haskell-lens

4
推荐指数
1
解决办法
90
查看次数

Haskell镜头:视图没有像结束和设置那样引用?

第一次使用lenssetover变得足够简单,我认为这会很简单view:使用相同的方案来引用内部部分,但不提供新的值或函数。但是不。tst3 below gives the error below the code。有人知道发生了什么事吗?

-- Testing lenses
tst1 = set (inner . ix 0 . w) 9 outer
tst2 = over (inner . ix 0 . w) (+2) outer
tst3 = view (inner . ix 0 . w) outer       -- this line errors out

    * No instance for (Monoid Int) arising from a use of `ix'
    * In the first argument of `(.)', namely `ix 0' …
Run Code Online (Sandbox Code Playgroud)

haskell haskell-lens

4
推荐指数
1
解决办法
148
查看次数

如何摆脱这些明显多余的“未定义”?

我正在使用 GHC 9.2.2 并使用OverloadedRecordDotgeneric -lens。作为一个实验,我想使用重载点作为通用镜头功能(包括类型更改更新)的“前端”。

我有这些辅助定义:

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE OverloadedRecordDot #-}
import Control.Lens ( (&), (.~), Lens )
import Data.Generics.Product.Fields qualified as G
import GHC.Records (HasField (..))
import GHC.TypeLits (Symbol)
import GHC.Generics (Generic)

-- Basically a 'Control.Lens.Reified.ReifiedLens'.
newtype Lensy s t a b = Lensy (Lens s t a b)

pry :: Lensy s t a b -> Lens s t a b
pry (Lensy l) = l

-- Just …
Run Code Online (Sandbox Code Playgroud)

haskell type-inference haskell-lens

4
推荐指数
1
解决办法
139
查看次数

光学折叠类型的Monoid r =&gt; Const r如何广义化为Contravariant + Applicative?

从这种Getter类型开始

type Getter s a = forall r. (a -> Const r a) -> s -> Const r s
Run Code Online (Sandbox Code Playgroud)

我们需要一个额外的Monoid约束来获得Fold

type Fold s a = forall r. Monoid r => (a -> Const r a) -> s -> Const r s
Run Code Online (Sandbox Code Playgroud)

但是Fold的实际和更一般的类型是

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

我了解这Contravariant是用来排除的Identity,因此确保我们只能获得价值。但是我不明白怎么Monoid r对应Applicative …

haskell lenses haskell-lens

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

标签 统计

haskell ×10

haskell-lens ×10

lenses ×4

atomic ×1

ioref ×1

type-inference ×1