标签: haskell-lens

潜行镜头和CPS超过了价值限制

在OCaml中编码了一种van Laarhoven镜头,但由于价值限制我很难.

相关代码如下

module Optic : sig
  type (-'s, +'t, +'a, -'b) t
  val lens : ('s -> 'a) -> ('s -> 'b -> 't) -> ('s, 't, 'a, 'b) t
  val _1 : ('a * 'x, 'b * 'x, 'a, 'b) t
end = struct
  type (-'s, +'t, +'a, -'b) t = 
    { op : 'r . ('a -> ('b -> 'r) -> 'r) -> ('s -> ('t -> 'r) -> 'r) }

  let lens …
Run Code Online (Sandbox Code Playgroud)

ocaml value-restriction haskell-lens

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

什么是棱镜?

我正在努力更深入地了解lens库,因此我会使用它提供的类型.我已经有了一些镜片经验,并且知道它们有多么强大和方便.所以我转向棱镜,我有点迷失了.似乎棱镜允许两件事:

  1. 确定实体是否属于和类型的特定分支,如果属于,则捕获元组或单元中的基础数据.
  2. 解构和重构实体,可能在过程中对其进行修改.

第一点看起来很有用,但通常一个不需要来自实体的所有数据,并且^?使用普通镜头可以获得所讨论Nothing的字段不属于实体所代表的分支,就像使用棱镜一样.

第二点......我不知道,可能有用吗?

所以问题是:我可以用棱镜做些什么我不能用其他光学器件?

编辑:谢谢大家的优秀答案和进一步阅读的链接!我希望我能接受他们.

haskell haskell-lens

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

在Haskell的Lens库中,`ix`和`at`有什么区别?

我所知道的是一个有效,另一个没有.

上下文: 我有一个数据结构F,其中包含Data.Map.Map k S另一个数据结构S.我的目标是建立一个Lens给定的F,k并将描述一个领域S.

困难在于密钥k可能不存在于地图中.这很好,该函数可以在Maybe中包装它的返回.但是,我无法通过使用Maybe传播镜头at.在阅读了很多Stack Overflow答案之后,我遇到了这个问题.

事实证明,更换atix解决我的问题类型,如果我还换成(^.)(^?).

问题: 似乎at并且ix做同样的事情,至少在这方面Map.两者都拿一把钥匙并给那个钥匙的价值一个'镜头'.但是,ix似乎与函数组合运算符很好(.).两者有什么区别?


关闭主题咆哮:

我像下一个人一样喜欢中缀运算符,但Control.Lens包看起来有点过分了.对于具有某些英文名称和某个键的新用户而言,会降低学习曲线.由于Lens库中使用了大量的包装器类,如果您还不知道发生了什么,则特别难以深入了解类型签名.为了天堂,我的代码开始看起来像Perl.

haskell haskell-lens

26
推荐指数
1
解决办法
1527
查看次数

镜片和拉链有什么区别?

这是在Haskell中使用拉链的一个例子:

data Tree a = Fork (Tree a) (Tree a) | Leaf a
data Cxt a = Top | L (Cxt a) (Tree a) | R (Tree a) (Cxt a)
type Loc a = (Tree a, Cxt a)

left :: Loc a -> Loc a
left (Fork l r, c) = (l, L c r)

right :: Loc a -> Loc a
right (Fork l r, c) = (r, R l c)

top :: Tree a -> Loc a 
top …
Run Code Online (Sandbox Code Playgroud)

haskell functional-programming clojure zipper haskell-lens

25
推荐指数
2
解决办法
3028
查看次数

为什么类型同义词中的类约束需要RankNTypes

编译好:

type List a = [a]
Run Code Online (Sandbox Code Playgroud)

但是当我引入类约束时,编译器要求RankNTypes包括:

type List2 a = Num a => [a]
Run Code Online (Sandbox Code Playgroud)

包含该扩展后,它编译得很好.为什么编译代码需要扩展名?

编辑:为什么我首先需要约束?

我检查这个镜头类型(type RefF a b = Functor f => (b -> f b) -> (a -> f a)从)这个职位,并发现它实际需要的RankNTypes,因为的Functor约束.

haskell higher-rank-types haskell-lens

25
推荐指数
1
解决办法
1897
查看次数

如何组合镜头(不构成)

在没有镜头的haskell中,我可以做以下事情:

data Item = Item { quantity :: Double, price ::Double }

cost :: Item -> Double
cost = (*) <$> quantity <*> price
Run Code Online (Sandbox Code Playgroud)

如果我使用镜头,我该怎么做相同的?我能做的最好的是

cost = to $ (*) <$> (^. quantity) <*> (^. price)
Run Code Online (Sandbox Code Playgroud)

有没有更好的办法 ?(当然我想要一个getter或同等的)

haskell haskell-lens

21
推荐指数
1
解决办法
498
查看次数

使用镜头读取多个字段

鉴于类型

data Prisoner = P { _name   :: String
                  , _rank   :: Int
                  , _cereal :: Cereal }

data Cereal = C { _number             :: Int
                , _percentDailyValue  :: Map String Float
                , _mascot             :: String }
Run Code Online (Sandbox Code Playgroud)

我可以通过模式匹配来提取某人的姓名,等级和谷物数量:

getNameRankAndCerealNumber_0 :: Prisoner -> (String, Int, Int)
getNameRankAndCerealNumber_0 (P { _name=name
                                , _rank=rank
                                , _cereal = C { _number=cerealNumber }}
                             ) = (name, rank, cerealNumber)
Run Code Online (Sandbox Code Playgroud)

或者,我可以使用镜头分别提取每个部分

makeLenses ''Cereal
makeLenses ''Prisoner

getNameRankAndCerealNumber_1 :: Prisoner -> (String, Int, Int)
getNameRankAndCerealNumber_1 p = (p ^. …
Run Code Online (Sandbox Code Playgroud)

haskell haskell-lens

20
推荐指数
2
解决办法
1626
查看次数

对于Control.Lens.Setter来说,在函子中包装类型不是多余的吗?

我正在观看Control.Lens介绍视频.
这让我想知道为什么Setter类型需要在仿函数中包装它.
它(大致)定义如下:

type Control.Lens.Setter s t a b = (Functor f) => (a -> f a) -> s -> f t
Run Code Online (Sandbox Code Playgroud)

假设我有一个名为Pointthis的定义数据:

data Point = Point { _x :: Int, _y :: Int } deriving Show
Run Code Online (Sandbox Code Playgroud)

然后我可以xlens像这样写自己的:

type MySetter s t a b = (a -> b) -> s -> t
xlens :: MySetter Point Point Int Int
xlens f p = p { _x = f (_x p) …
Run Code Online (Sandbox Code Playgroud)

haskell functor applicative lenses haskell-lens

20
推荐指数
2
解决办法
388
查看次数

是否有可能懒散地获得Traversable的所有上下文?

lensoffer holesOf,这是这个假设函数的一个更通用和更强大的版本:

holesList :: Traversable t
          => t a -> [(a, a -> t a)]
Run Code Online (Sandbox Code Playgroud)

给定一个容器,holesList生成一个容器元素列表以及替换这些元素的函数.

holesList类似于真实的类型holesOf,无法捕获生成的对数等于容器元素数的事实.因此,更美丽的类型将是

holes :: Traversable t
      => t a -> t (a, a -> t a)
Run Code Online (Sandbox Code Playgroud)

我们可以holes通过使用holesList制作一个列表然后遍历来State重新填充元素来实现.但这有两个原因令人不满意,其中一个原因具有实际后果:

  1. slurping代码将有一个无法访问的错误调用来处理在遍历完成之前列表为空的情况.这很恶心,但对使用该功能的人来说可能并不重要.

  2. 无限延伸到左侧或左下方的容器根本不起作用.向左延伸很远的容器处理效率非常低.

我想知道是否有任何办法解决这些问题.使用Magma镜头之类的东西很有可能捕捉到遍历的形状:

data FT a r where
  Pure :: r -> FT a r
  Single :: a -> FT a a
  Map :: (r -> s) -> FT a r -> FT …
Run Code Online (Sandbox Code Playgroud)

haskell haskell-lens traversable

20
推荐指数
3
解决办法
1250
查看次数

Ramda js:具有嵌套对象数组的深层嵌套对象的镜头

使用Ramda.js(和镜头),我想修改下面的JavaScript对象,将具有ID ="/ 1/B/i"的对象的"NAME:VERSION1"更改为"NAME:VERSION2".

我想使用镜头,因为我只想更改一个深度嵌套的值,但保持整个结构不变.

我不想使用lensIndex,因为我永远不知道数组的顺序,所以相反,我想通过查找它的"id"字段来"找到"数组中的对象.

我可以用镜头做这个,还是应该用不同的方式做?

{
  "id": "/1",
  "groups": [
    {
      "id": "/1/A",
      "apps": [
        {
          "id": "/1/A/i",
          "more nested data skipped to simplify the example": {} 
        }
      ]
    },
    {
      "id": "/1/B",
      "apps": [
        { "id": "/1/B/n", "container": {} },
        {
          "id": "/1/B/i",

          "container": {
            "docker": {
              "image": "NAME:VERSION1",
              "otherStuff": {}
            }
          }
        }
      ]
    }

  ]
}
Run Code Online (Sandbox Code Playgroud)

javascript haskell-lens ramda.js

19
推荐指数
2
解决办法
1万
查看次数