问题描述
如果我有这样的记录:
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
也许在库中有一些泛型帮助程序,但是我不知道有任何此类事情。
请注意,如果edgeList
不长四个元素,则以上代码将在运行时使程序崩溃。如果列表来源不受信任,则可能需要验证列表,例如使用case of
并更优雅地处理意外长度。
如果您确信所使用的列表将始终仅包含4个元素,那么与Haskell一样,模式匹配是最好的,最易读的选项:
edgeSet = let [a,b,c,d] = edgeList in EdgeSet a b c d
,如果您需要重用它,可以轻松地将其提取到函数中。
请注意,正如我所暗示的,如果给出的长度小于4的列表将崩溃,但是您给出的解决方案也将崩溃。 (实际上,您将使用长度为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,d] = EdgeSet a b c d
您必须知道列表的长度为4。