繁体   English   中英

用于元组扩展的镜头?

[英]lenses for tuple extension?

Control.Lens.Tuple定义镜头以访问元组元素。 例如

class Field3 s t a b | s -> a, t -> b, s b -> t, t a -> s where
  -- | Access the 3rd field of a tuple.
  _3 :: Lens s t a b

  -- >>> (1,2,3)^._3
  -- 3
  --
  -- >>> _3 .~ "hello" $ (1,2,3)
  -- (1,2,"hello")

setter _3 .~将第三个元素更改的元组返回到本例中的其他类型。

对于类Field3 ,为具有三个或更多元素的元组定义了实例。 不是对/两对,因为得到的是什么?

但是如果setter可以改变第n个元素的类型,为什么它不能将类型更改为元组的不同元素?

  -- >>> _3 .~ "hello" $ (1,2)
  -- (1,2,"hello")

也就是说,一个setter _3 .~通过扩展一个二元组来设置第三个元素。

instance Field3 (a,b) (a,b,c') Dummy c' where
  _3 k ~(a,b) = k undefined <&> \c' -> (a,b,c')

其中Dummyundefined是一个占位符类型和值,用于传入的两个不存在的第三个元素。

延伸到arity 3后,镜头_3照常工作; 镜头_1, _2也贯穿镜头规律。

Q1。 这适用于制定者吗?
(当然它不适用于更新者/ over

Q2。 如果是这样,是否有某种方法可以让它看起来不合适,以尝试view不存在的第3个元素?

Q3。 如果setter不起作用,是否会有一个可以实现效果的extend运算符? (大概使用不同的算子。)

也许这个例子可能就是这样

instance Field3 (a,b) (a,b,c') (a,b) c' where
  _3 k ~(a,b) = k (a,b) <&> \c' -> (a,b,c')

这样view将返回一个古怪的输入结果,并over可能的前两个建立的第三个元素。

在van Laarhoven透镜配方中,光学元件只是一个高阶函数,它可以对较小的结构采取动作,对较大的结构采取动作。 这些功能可以组成,然后与lens包装中提供的糖一起使用,使他们无所谓。 但它们也可以被称为。

假设你有这个:

bigStructure :: (Int, (Int, (Int, Int)))
bigStructure = (0, (1, (2, 3)))

并且你想在最里面的一对上追加10 这是对该对的一个动作,这是一个较小的大结构。

mk3ple :: c -> (a, b) -> (a, b, c)
mk3ple = flip $ uncurry (,,)

所以_2 . _2 _2 . _2是一个专注于最里面的镜头的镜头 - 换句话说,它是一个功能,它在最内层对上采取动作对大结构的动作。 所以,让我们......将mk3ple传递给它( over这个;它只是为我们处理一些Identity繁忙的工作):

over (_2 . _2) (mk3ple 10) bigStructure

而且你有一个针对bigStructure的setter(概念,即;不是文字Setter ),它使用你需要关注元组的任何镜头。


当然,如果你更愿意把元组音符变成一个带有吸气剂和一切的实际镜头,你当然也可以这样做! 只需将单元视为每个元组的一部分,并写:

mk3ple' :: Lens (a, b) (a, b, c) () c
mk3ple' = lens (const ()) (uncurry (,,))

set (_2 . _2 . mk3ple') 10 bigStructure

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM