我正在构建舒适,通过一些Haskell玩具问题,我编写了下面的代码
multipOf :: [a] -> (Int, a)
multipOf x = (length x, head x)
gmcompress x = (map multipOf).group $ x
它成功地预置了以下操作
gmcompress [1,1,1,1,2,2,2,3] = [(4,1),(3,2),(1,3)]
现在,我想要这个函数,而不是告诉我集合中的一个元素具有多重性。所以给出了结果(4,1),(3,2),3。如果有一种方法(无论是在将列表转换成对的过程中还是之后),对于所有多重性1的元素来说,都是很棒的,那么只留下一个元素;否则,就说成对。我最初天真的想法是做以下事情。
multipOf :: [a] -> (Int, a)
multipOf x = if length x = 1 then head x else (length x, head x)
gmcompress x = (map multipOf).group $ x
但这不管用。我认为,因为then
和else
子句有不同的类型,而且不幸的是,您不能按分段定义函数的(Co)域。我该如何解决这个问题呢?
发布于 2015-10-24 00:54:26
但这不管用。我认为,因为当时和其他子句有不同的类型,不幸的是,您不能按分段定义函数的(Co)域。我该如何解决这个问题呢?
您的诊断是正确的;then
和else
必须有相同的类型。严格地说,没有“解决这个问题”。无论采用什么解决方案,都必须在条件的两个分支中使用相同的类型。一种方法是设计一个自定义数据类型,它编码您想要的可能性,然后使用它。像这样的东西会有用的:
-- | A 'Run' of @a@ is either 'One' @a@ or 'Many' of them (with the number
-- as an argument to the 'Many' constructor).
data Run a = One a | Many Int a
但说实话,我不认为这会给你带来什么好处。我会坚持(Int, a)
编码,而不是使用这个Run
类型。
https://stackoverflow.com/questions/33312250
复制相似问题