haskell - 使用兼容的总和更新来自 sop-core 的 n 元乘积

标签 haskell algebraic-data-types type-level-computation

我正在与 sop-core 合作库,我想编写一个具有以下类型的函数:

patch :: NS I xs -> NP Maybe xs -> NP Maybe xs

xs 是类型级别的列表,例如 '[Int,Char,Bool]I是一个恒等仿函数。 NS I xs是一个n元求和类型。 NP Maybe xs是一个 n 元产品,其中每个组件可能存在也可能不存在。

patch 应该从 n 进制和中获取值并填充 n 进制乘积的相应槽,如果它已经存在则覆盖它。例如:

patched :: NP Maybe '[Int,Char,Bool]
patched = patch (Z (I 3)) (Nothing :* Nothing :* Nothing :* Nil)
-- patched == Just 3 :* Nothing :* Nothing :* Nil

我怀疑解决方案可能涉及 injections功能,但我很困惑。

最佳答案

该解决方案不需要 injections毕竟,但是expand_NS函数,通过用默认值填充乘积的不匹配部分,将总和转换为乘积。

诀窍是构建一个setters的乘积,我们可以使用liftA2_NP将其应用于原始记录。 。当我们扩展总和时,不匹配的部分将被恒等函数填充。但是我们用总和中的值覆盖匹配的组件。

首先我们需要这个辅助类型

newtype Mendo a = Mendo { getMendo :: Maybe a -> Maybe a }

补丁的代码为:

patch :: forall xs. SListI xs => NS I xs -> NP Maybe xs -> NP Maybe xs
patch piece =
  let mendos :: NP Mendo xs -- product of setters
      mendos = expand_NS (Mendo id) (liftA_NS (\(I x) -> Mendo (\_ -> Just x)) piece)
   in liftA2_NP (\(Mendo f) x -> f x) mendos

关于haskell - 使用兼容的总和更新来自 sop-core 的 n 元乘积,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58573934/

相关文章:

f# - 如何将 FParsec 结果值提取到 FSI 中的变量

scala - 测试某些东西不能编译的断言

haskell - Haskell 中的递归

list - 如何连接两个 Snoc 列表?

scala - case 类中的 var 成员会影响 case 类的相等性吗?

scala - Shapeless Witness 以及它如何给出实际的单例类型

scala - 嵌套案例类之间的递归转换,其中目标中的字段是源类的未对齐子集

haskell - 如何获得一致的标准基准,或跨运行解释结果?

algorithm - 是否有可能出现一个懒散的,广度优先的单峰玫瑰树?

haskell - 在 Haskell 中应用函数并包装在元组中