映射同类记录类型
Mapping homogeneous record type
假设我们有一个同类的记录类型。
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
?
要在类型级别获得从 Int
到 String
的自由转换,只需为您的记录提供一个参数,然后使用 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
,您可以先转换为 Foreign.Object
using fromHomogeneous
,然后将函数映射到它上面,然后再转换回记录。
不幸的是没有toHomogeneous
函数,因为通常你不能确定Foreign.Object
是否真的包含所有需要的键。但没关系:在这种特殊情况下,您可以确定它确实如此,因此您可以摆脱 unsafeCoerce
:
mapItoS :: forall a b. (a -> b) -> Rec a -> Rec b
mapItoS f = fromHomogeneous >>> map f >>> unsafeCoerce
一个与问题严格相关的小型自插件:-P 我刚刚发布了一个库,它提供了许多允许 PureScripter 使用同类 Record
和 Variant
的实例:
https://pursuit.purescript.org/packages/purescript-homogeneous
我认为它应该比 heterogeneous
这样的解决方案有更好的推理。请检查一下,让我知道您的想法。
假设我们有一个同类的记录类型。
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
?
要在类型级别获得从 Int
到 String
的自由转换,只需为您的记录提供一个参数,然后使用 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
,您可以先转换为 Foreign.Object
using fromHomogeneous
,然后将函数映射到它上面,然后再转换回记录。
不幸的是没有toHomogeneous
函数,因为通常你不能确定Foreign.Object
是否真的包含所有需要的键。但没关系:在这种特殊情况下,您可以确定它确实如此,因此您可以摆脱 unsafeCoerce
:
mapItoS :: forall a b. (a -> b) -> Rec a -> Rec b
mapItoS f = fromHomogeneous >>> map f >>> unsafeCoerce
一个与问题严格相关的小型自插件:-P 我刚刚发布了一个库,它提供了许多允许 PureScripter 使用同类 Record
和 Variant
的实例:
https://pursuit.purescript.org/packages/purescript-homogeneous
我认为它应该比 heterogeneous
这样的解决方案有更好的推理。请检查一下,让我知道您的想法。