我正在与 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/