标签: haskell-lens

使用镜头修改所有偶数​​值

假设我有一个这样的数组: [1, 2, 3, 4]

如何使用镜头包仅修改偶数值?我正在寻找类似的东西:

filterLens even (+10) $ [1, 2, 3, 4]
=> [1, 12, 3, 14]
Run Code Online (Sandbox Code Playgroud)

haskell haskell-lens

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

融合遍历

Traversable的论文给出了融合monoidal和一元遍历这听起来真的很有趣的18-19页上的一个例子,但我被他们的LaTex的混淆.

cciBody :: Char -> Count a
wciBody :: Char -> (|M| (State Bool) DotInASquare Count) a
Run Code Online (Sandbox Code Playgroud)

结果令人惊讶:

(traverse cciBody) xInACircle (traverse wciBody)
Run Code Online (Sandbox Code Playgroud)

是相同的:

traverse (cciBody xInACircle wciBody)
Run Code Online (Sandbox Code Playgroud)

我认为结果的类型是:

Count XInASquare (|M| (State Bool) DotInASquare Count) [a]
Run Code Online (Sandbox Code Playgroud)

但不是100%肯定.说话表情符号的人可以告诉我它应该如何看待Haskell吗?

更新

我认为xInACircle可能是一个中缀sequenceA.类型匹配.或者也许它只是(,)一个实例Traversable.<*>即使结果看起来有点像,t (x <*> y) = t x <*> t y但它们在文章中没有使用Wingding,这绝对不是<*>.

更新2

xInACircle的类型是(Functor m,Functor n)⇒(a→mb)→(a→nb)→(a→(m XInASquare n)b).提醒你什么?不是我.

haskell traversal haskell-lens

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

使用记录语法在Haskell中编写OOP样式的"setter"函数

我正在阅读有关镜头的教程,在介绍中,作者lens通过展示我们如何使用标准Haskell实现OOP风格的"setter"/"getter"的一些示例来激发这一概念.我对以下示例感到困惑.

假设我们User根据图1(下面)定义代数数据类型.本教程(正确地)指出我们可以通过NaiveLens数据类型和nameLens函数实现"setter" 功能(也在图1中).图2给出了一个示例用法.

我很困惑为什么我们需要这样一个精心设计的构造(即NaiveLens数据类型和nameLens函数)来实现"setter"功能,当下面的(有点明显的)函数似乎同样很好地完成工作时:set' a s = s {name = a}.

但是,鉴于我的"显而易见"功能正是lambda函数的一部分nameLens,我怀疑使用下面的结构确实有一个优势,但我太密集了,看不出那个优点是什么.我希望其中一个Haskell向导可以帮助我理解.

图1(定义):

data User = User { name :: String
                 , age :: Int
                 } deriving Show

data NaiveLens s a = NaiveLens { view :: s -> a
                               , set :: a -> s -> s
                               }

nameLens :: NaiveLens User String
nameLens = NaiveLens name (\a s -> s …
Run Code Online (Sandbox Code Playgroud)

haskell record haskell-lens

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

使用镜头组成功能

考虑具有以下(伪)签名的"组合"函数:

(a1 -> a2 -> ... -> an -> r) -> 
(s -> ai) -> 
a1 -> a2 -> ... -> ai -> ... an -> r
where i in [1..n]
Run Code Online (Sandbox Code Playgroud)

当然我们不能在Haskell中编写上面的内容,但这是一个具体的例子:

f4change3 :: 
  (a1 -> a2 -> a3 -> a4 -> r) -> 
  (s -> a3) -> 
  a1 -> a2 -> s -> a4 -> r
f4change3 f g x1 x2 x3 x4 = f x1 x2 (g x3) x4
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,narity的每个函数都有一组函数n,因此我们需要的函数数量与arity呈二次方式增长.

我可以写出我需要的那些,但首先,我不想重新发明轮子,所以很高兴知道库是否已经完成了这个.但是,虽然我几乎没有使用镜头,但我已经阅读了一些关于它们的内容,这种问题似乎正好在他们的盟友身上,但我不确定该怎么做.如果可能的话,一些示例代码会很棒.

haskell lenses haskell-lens

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

证明在Haskell镜头库中断言的类型等价性

根据镜头教程:

type Getting b a b  = (b -> Const b b) -> (a -> Const b a)

-- ... equivalent to: (b ->       b  ) -> (a ->       b  )

-- ... equivalent to:                     (a ->       b  )
Run Code Online (Sandbox Code Playgroud)

问题:为什么(b -> b) -> (a -> b)相当于(a -> b)

haskell haskell-lens

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

如何撰写"可能"镜头?

如果我有一个嵌套记录的镜头,每个镜头返回一个Maybe,我怎么能让它们组成,所以如果"遍历"中的任何内容返回一个Nothing最后的结果是Nothing

data Client = Client
  {
    clientProperties :: Maybe Properties
  , ...
  }

data Properties = Properties
  {
    propSmtpConfig :: Maybe SmtpConfig
  , ...
  }

c :: Client 
c = undefined

smtp = c ^. (properties . smtpConfig) -- How to make these lenses compose?
Run Code Online (Sandbox Code Playgroud)

编辑我尝试了很多选项,但这是我能想到的最好的选择.寻找更清洁的东西:

(client ^. properties) >>= (view smtpConfig)
Run Code Online (Sandbox Code Playgroud)

haskell haskell-lens

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

循环镜头,并使用每个镜头和设置

这是我一直在处理的一些代码的版本,删除了细节.希望很清楚我正在尝试做什么,但如果没有,我可以澄清.我很擅长使用镜头,所涉及的复杂类型往往使它们看起来比它们的价值更麻烦.

-- some data type
type AType = ...

data Thing = Th { _v, _w, _x :: AType, _otherStuff :: ... }

makeLenses ''Thing

-- some operation that can be performed on corresponding x or w or v values in two Things.
f :: AType -> AType -> AType
f = ...

-- apply f to the corresponding v, and w, and x values in a and b; then store each result in the respective field of a, leaving …
Run Code Online (Sandbox Code Playgroud)

haskell haskell-lens

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

没有模板haskell的多形态镜头

我试图为多种类型创建一个多态镜头decleration(没有模板haskell).

module Sample where
import Control.Lens
data A = A {_value:: Int}
data B = B {_value:: Int}
data C = C {_value:: String}
value = lens _value (\i x -> i{_value=x}) -- <<< ERROR
Run Code Online (Sandbox Code Playgroud)

但我得到以下错误:

Ambiguous occurrence ‘_value’
It could refer to either the field ‘_value’,
                         defined at library/Sample.hs:5:13
                      or the field ‘_value’, defined at 
library/Sample.hs:4:13
                      or the field ‘_value’, defined at 
library/Sample.hs:3:13
  |
6 | value = lens _value (\i x -> i{_value=x}) -- <<< ERROR
  |              ^^^^^^ …
Run Code Online (Sandbox Code Playgroud)

polymorphism haskell haskell-lens

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

为什么镜头包含一个用于fromEnum/toEnum的Iso,而不是一个用于显示/读取的?

假设你声明了两个同构

showing :: (Read a, Show a) => Iso' String a
showing = iso read show

reading :: (Read a, Show a) => Iso' a String
reading = iso show read
Run Code Online (Sandbox Code Playgroud)

它们是不安全的,并不是每个String都会解析为a.

这引出了一个问题:为什么这两个不包含在库enum = iso fromEnum toEnum中?

它同样不安全,不能通过类型系统来防止.他们都把负担转嫁给程序员,程序员必须确保转换不会破坏同构.

快速示例:under enum (+1) True将抛出异常

haskell haskell-lens

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

用于获取或设置由运行时参数确定的记录字段的镜头

我有这些类型(还有更多):

data Player = PlayerOne | PlayerTwo deriving (Eq, Show, Read, Enum, Bounded)

data Point = Love | Fifteen | Thirty deriving (Eq, Show, Read, Enum, Bounded)

data PointsData =
  PointsData { pointsToPlayerOne :: Point, pointsToPlayerTwo :: Point }
  deriving (Eq, Show, Read)
Run Code Online (Sandbox Code Playgroud)

我正在做Tennis kata,作为实现的一部分,我想使用一些函数,这些函数使我能够为任意播放器获取或设置积分,只有在运行时才能知道。

正式地,我需要像这样的功能:

pointFor :: PointsData -> Player -> Point
pointFor pd PlayerOne = pointsToPlayerOne pd
pointFor pd PlayerTwo = pointsToPlayerTwo pd

pointTo :: PointsData -> Player -> Point -> PointsData
pointTo pd PlayerOne p …
Run Code Online (Sandbox Code Playgroud)

haskell lenses haskell-lens

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

标签 统计

haskell ×10

haskell-lens ×10

lenses ×2

polymorphism ×1

record ×1

traversal ×1