标签: lenses

如何使用 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
查看次数

如何使用"Of"镜头?(Haskell的)

我想写:

minimum $ map _x elems
Run Code Online (Sandbox Code Playgroud)

使用镜头.我想使用minimumOf镜头,但我无法弄清楚如何使用它的类型.

我正在寻找类似的东西

elems ^.. minimumOf x
Run Code Online (Sandbox Code Playgroud)

但它没有打字检查:

Prelude Control.Lens Data.Map> let elems = [(1,2),(3,4)] :: [(Double, Double)]
Prelude Control.Lens Data.Map> elems ^.. minimumOf _1

<interactive>:62:11:
    Couldn't match type ‘Maybe a0’
                  with ‘[(Double, Double)]
                        -> Const (Data.Monoid.Endo [a]) [(Double, Double)]’
    Expected type: Getting (Data.Monoid.Endo [a]) [(Double, Double)] a
      Actual type: (a -> Const (Data.Monoid.Endo [a]) a) -> Maybe a0
    Relevant bindings include it :: [a] (bound at <interactive>:62:1)
    Possible cause: ‘minimumOf’ is applied …
Run Code Online (Sandbox Code Playgroud)

haskell lenses

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

为列表创建镜头(如)

我正在尝试为以下数据结构创建镜头.我正在使用lens-family.

data Tree = Tree {
        _text :: String,
        _subtrees :: [Tree]
    } deriving (Show,Eq,Read,Generic)
Run Code Online (Sandbox Code Playgroud)

我想出于各种原因避免使用Template Haskell.首先,它似乎不适用于我的ghc版本(7.8.3),这是另一个(超出范围)问题.

为记录制作镜头并不难.

text :: Lens' Tree String
text f (Tree text' subtrees') =
  (\text'' -> Tree text'' subtrees') `fmap` (f text')

subtrees :: Lens' Tree [Tree]
subtrees f (Tree text' subtrees') =
  (\subtrees'' -> Tree text' subtrees'') `fmap` (f subtrees')
Run Code Online (Sandbox Code Playgroud)

但似乎镜头系列没有列表的默认镜头.我认为这是可能的.有lens包裹.这些是我失败的尝试:

import Lens.Family2
import Lens.Family2.Unchecked
-- List lenses
_last :: Lens [a] [a'] a a'
_last f l = …
Run Code Online (Sandbox Code Playgroud)

haskell lenses

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

如何使用单片眼镜更新地图

我想尝试Monocle库.但我找不到基本语法的帮助资源.

总之,我需要Map[K,V] -> A具有光学器件的光学器件V -> A,我该如何定义它?

假设我有一些

import monocle.macros.GenLens

case class DirState(opened: Boolean)

object DirState {
  val opened = GenLens[DirState](_.opened)
}

type Path = List[String]
type StateStore = Map[Path, DirState]
Run Code Online (Sandbox Code Playgroud)

接下来我遇到了我需要简单的地方StateStore => StateStore,所以我正在导入

import monocle._
import monocle.std._
import monocle.syntax._
import monocle.function._
Run Code Online (Sandbox Code Playgroud)

并尝试先定义:

def setOpened(path: Path): StateStore => StateStore = 
  at(path) composeLens DirState.opened set true
Run Code Online (Sandbox Code Playgroud)

到这里来

暧昧隐式的值:这两个方法atMaptrait MapInstances类型[K, V]=> monocle.function.At[Map[K,V],K,V] 和方法atSettrait SetInstances类型的[A]=> monocle.function.At[Set[A],A,Unit] …

scala lenses monocle-scala

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

Scala Lenses在我的项目中的位置?

实际上我一直坚持功能编程代码风格和项目结构.用Java编程我知道在哪里放置我的逻辑,但我不熟悉函数风格.

实际上我尝试让我当前项目中的Scala类不可变.然后我想使用scalaz.Lens和scalaz.PLens来改变我的对象(实际创建新的).

在所有Lense示例中,人们将代码放在一个对象中,这扩展了App trait以简单地展示它是如何工作的.但在现实生活中的例子应该是一些适当的地方来写那些镜头.

在Java中,所有mutators和accessors都放在类本身中.但是对于镜头我不知道在哪里写它们.

将不胜感激任何建议

scala lenses

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

Monocle的Optionals与部分镜头相同吗?

Monocle的选项具有以下访问功能(for Optional[C,A]):

getOption: C => Option[A]
set: A => C => C
Run Code Online (Sandbox Code Playgroud)

这与(部分)非对称数据镜头的原始定义不一致.我希望:

getOption: C => Option[A]
setOption: A => C => Option[C]
Run Code Online (Sandbox Code Playgroud)

这是什么原因?如何使用Monocle获得经典的局部镜片?在对镜头进行编程时,我发现确保整体设置比获取镜头要困难得多......

scala lenses monocle-scala

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

按值修改Haskell嵌套记录

说我有一个嵌套的结构,如下所示:

data Bar = Bar { _id :: Integer, _bars :: [Bar] }
data Foo = Foo { _bars :: [Bar] }
Run Code Online (Sandbox Code Playgroud)

我有Foo一堆Bars与各种ids 在一起:

foo = Foo [Bar 1 [Bar 2], Bar 3 [Bar 4, Bar 5]]
Run Code Online (Sandbox Code Playgroud)

怎么办,可能使用的镜头,我修改foo,从而Bar 5成为Bar 6

我知道我曾经fclabels做过这样的事情:

mkLabel ''Foo
mkLabel ''Bar
modify bars (\bars -> ...) foo
Run Code Online (Sandbox Code Playgroud)

但是条可以无限嵌套。如何找到并修改Bar具有指定ID的?

haskell records template-haskell lenses

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

使用Maybe遍历嵌套记录的更短方法

是否有更短/更清晰的方式编写以下代码片段:

fromMaybe "" $ fmap (^. fullName) (bi ^. bookerContact)
Run Code Online (Sandbox Code Playgroud)

bi ^. bookerContact可能会导致Maybe Contact记录,这就是^. fullName需要fmap的原因.在嵌套遍历之后,如果我们最终得到一个Nothing我们用fromMaybe ""它来默认它为空字符串.

haskell lenses haskell-lens

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

如果对象类型可扩展,我应该如何指向记录字段?

在Reason中思考一种在对象上定义简单镜头的方法。

我尝试..通过以下代码使用可扩展对象(在字段列表之前):

type hasName('a, 't) = {.. name: 't} as 'a;
type lens('s, 'v) = {
  get: 's => 'v,
  set: ('s, 'v) => 's,
};
let nameLens: lens(hasName('a, 't), 't) = {
  get: s => s.name,
  set: (s, v) => {...s, name: v},
}
Run Code Online (Sandbox Code Playgroud)

我收到“找不到记录字段名称”。错误,尽管类型hasName肯定应该有一个...我在这里做错了什么?

免责声明:我真的是Reason / OCaml的新手,所以我可能会错过一些显而易见的事情。

ocaml object lenses reason

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

如何为特定类型实现类似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
查看次数