映射同质记录类型



假设我们有一个同构的记录类型。

type RecI = { a :: Int, b :: Int, c :: Int, d :: Int, e :: Int }

我们想从中获得具有相同密钥但不同值类型的类型:

type RecS = { a :: String, b :: String, c :: String, d :: String, e :: String }

是否可以在不显式定义RecI的所有密钥的情况下获得RecS类型?

问题的第二部分,实现从一种类型到另一种类型的映射功能的最佳方法是什么:

mapItoS :: (Int -> String) -> RecI -> RecS

要在类型级别获得从IntString的免费ish转换,只需给您的记录一个参数,然后用Int实例化它以获得RecI,用String实例化它以获取RecS:

type Rec a = { a :: a, b :: a, c :: a, d :: a, e :: a }
type RecI = Rec Int
type RecS = Rec String

要实现mapItoS,您可以首先使用fromHomogeneous转换为Foreign.Object,然后在其上映射函数,然后转换回记录。

不幸的是,没有toHomogeneous函数,因为通常情况下,您无法确定Foreign.Object是否包含所有必需的密钥。但没关系:在这种特殊情况下,你可以确信它确实存在,所以你可以逃脱unsafeCoerce:

mapItoS :: forall a b. (a -> b) -> Rec a -> Rec b
mapItoS f = fromHomogeneous >>> map f >>> unsafeCoerce

一个与以下问题严格相关的小型自插件:-p我刚刚发布了一个库,它提供了许多实例,允许PureScripter使用同构的RecordVariant:

https://pursuit.purescript.org/packages/purescript-homogeneous

我认为它应该比heterogeneous这样的解决方案有更好的推断。请检查一下,让我知道你的想法。

最新更新