gpt4 book ai didi

haskell - 用于元组扩展的透镜?

转载 作者:行者123 更新时间:2023-12-02 19:04:49 25 4
gpt4 key购买 nike

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,为具有三个或更多元素的元组定义了实例。不适用于成对/两对,因为 getter 会得到什么?

但是如果 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)

第二季度。如果是这样,是否有某种方法可以使其类型错误地尝试查看不存在的第三个元素?

第三季度。如果 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 可能会从前两个元素构建第三个元素。

最佳答案

在范拉尔霍文透镜公式中,光学器件只是一个高阶函数,它将对较小结构的作用转化为对较大结构的作用。这些函数可以组合起来,然后与lens包中提供的糖一起使用,以使调用它们变得无意识。但也可以直接调用它们。

假设你有这个:

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

并且您想将 10 附加到最里面的对。这是对该对的操作,它是大结构中较小的一部分。

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

所以_2。 _2 是一个聚焦于最内层对的镜头,换句话说,它是一个对最内层对采取行动以对大结构采取行动的函数。因此,让我们...将 mk3ple 传递给它(over 执行此操作;它只是为我们处理一些 Identity 繁忙工作):

over (_2 . _2) (mk3ple 10) bigStructure

现在,您已经找到了一个用于 bigStructure 的 setter(概念性的,即,不是字面上的 Setter),它使用您需要关注元组的任何镜头。

<小时/>

当然,如果您希望 tuple-appender 是一个带有 setter/getter 和所有东西的实际镜头,您当然也可以这样做!只需将单位视为每个元组的一部分,然后编写:

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

set (_2 . _2 . mk3ple') 10 bigStructure

关于haskell - 用于元组扩展的透镜?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55981177/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com