是否可以使用 Haskell 中的列表填充记录?
Is it possible to populate a record using a list in Haskell?
如果我有这样的记录:
data EdgeSet = EdgeSet {
top :: Int,
right :: Int,
bottom :: Int,
left :: Int,
} deriving (Show)
是否可以通过匹配类型列表填充属性?
我正在追逐以下内容:
...
where
edgeList = [1, 2, 3, 4]
edgeSet = EdgeSet {edgeList}
如果没有,有什么想法可以让我比现在更简洁一点吗?
EdgeSet {top=edgeList !! 0, left=edgeList !! 1, bottom=edgeList !! 2, right=edgeList !! 3}
我想不出比
更短的东西
where
-- given
edgeList = [1, 2, 3, 4]
-- split into components and call the constructor
[x1,x2,x3,x4] = edgeList
edgeSet = EdgeSet x1 x2 x3 x4
也许库中有一些 Generic helper,但我不知道有这样的东西。
请注意,如果 edgeList
不是四个元素长,上面的代码将在运行时使您的程序崩溃。如果列表来源不受信任,您可能想要验证列表,例如使用 case of
并更优雅地处理意外长度。
如果您确信您使用的列表始终恰好有 4 个元素,那么与 Haskell 一样,模式匹配是最好、最易读的选项:
edgeSet = let [a, b, c, d] = edgeList in EdgeSet a b c d
如果您需要重用它,您可以轻松地将其提取到一个函数中。
请注意,正如我所暗示的,如果给定一个长度小于四的列表,这将崩溃 - 但你给出的解决方案也会崩溃。 (实际上,您的列表将适用于长度为 5 或更长的列表,而我的则不会 - 但如果您愿意,您可以轻松调整模式以应对这种情况。)
我不知道 Haskell 提供了更好的语法来执行此操作。我会建议重新考虑您是否需要一个列表 - 将数据直接输入 EdgeSet
构造函数而不是通过列表可能会更容易和更惯用。这显然在一定程度上取决于您最初是如何获取数据的。
另请注意,如果您确定只有 4 个元素,则 4 元组的类型比列表安全得多,因为编译器随后会确保您拥有正确的数字。
可能不是您要找的东西,但总是可以按照以下方式做一些事情:
module EdgeSet where
data EdgeSet = EdgeSet {
top :: Int,
right :: Int,
bottom :: Int,
left :: Int
} deriving (Show)
class ListToMyClass a where
fromListToClass :: [Int] -> a
instance ListToMyClass EdgeSet where
fromListToClass [a,b,c,d] = EdgeSet a b c d
你必须知道列表的长度是 4。
如果我有这样的记录:
data EdgeSet = EdgeSet {
top :: Int,
right :: Int,
bottom :: Int,
left :: Int,
} deriving (Show)
是否可以通过匹配类型列表填充属性?
我正在追逐以下内容:
...
where
edgeList = [1, 2, 3, 4]
edgeSet = EdgeSet {edgeList}
如果没有,有什么想法可以让我比现在更简洁一点吗?
EdgeSet {top=edgeList !! 0, left=edgeList !! 1, bottom=edgeList !! 2, right=edgeList !! 3}
我想不出比
更短的东西where
-- given
edgeList = [1, 2, 3, 4]
-- split into components and call the constructor
[x1,x2,x3,x4] = edgeList
edgeSet = EdgeSet x1 x2 x3 x4
也许库中有一些 Generic helper,但我不知道有这样的东西。
请注意,如果 edgeList
不是四个元素长,上面的代码将在运行时使您的程序崩溃。如果列表来源不受信任,您可能想要验证列表,例如使用 case of
并更优雅地处理意外长度。
如果您确信您使用的列表始终恰好有 4 个元素,那么与 Haskell 一样,模式匹配是最好、最易读的选项:
edgeSet = let [a, b, c, d] = edgeList in EdgeSet a b c d
如果您需要重用它,您可以轻松地将其提取到一个函数中。
请注意,正如我所暗示的,如果给定一个长度小于四的列表,这将崩溃 - 但你给出的解决方案也会崩溃。 (实际上,您的列表将适用于长度为 5 或更长的列表,而我的则不会 - 但如果您愿意,您可以轻松调整模式以应对这种情况。)
我不知道 Haskell 提供了更好的语法来执行此操作。我会建议重新考虑您是否需要一个列表 - 将数据直接输入 EdgeSet
构造函数而不是通过列表可能会更容易和更惯用。这显然在一定程度上取决于您最初是如何获取数据的。
另请注意,如果您确定只有 4 个元素,则 4 元组的类型比列表安全得多,因为编译器随后会确保您拥有正确的数字。
可能不是您要找的东西,但总是可以按照以下方式做一些事情:
module EdgeSet where
data EdgeSet = EdgeSet {
top :: Int,
right :: Int,
bottom :: Int,
left :: Int
} deriving (Show)
class ListToMyClass a where
fromListToClass :: [Int] -> a
instance ListToMyClass EdgeSet where
fromListToClass [a,b,c,d] = EdgeSet a b c d
你必须知道列表的长度是 4。