"For all" 语句 Haskell
"For all" statements in Haskell
我正在通过一些 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)]
现在我想要这个函数,而不是告诉我集合中的一个元素具有多重性 1,而不是让它一个人呆着。因此,改为给出结果 [(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
子句有不同的类型,不幸的是你不能分段定义函数的(共同)域。我该如何解决这个问题?
BUT this doesn't work. I think because the then and else clauses have different types, and unfortunately you can't piece-wise define the (co)domain of your functions. How might I go about getting past this issue?
您的诊断是正确的; then
和 else
必须具有相同的类型。严格来说没有 "getting past this issue,"。无论您采用何种解决方案,都必须在条件的两个分支中使用相同的类型。一种方法是设计一个自定义数据类型来编码您想要的可能性,然后使用它。像这样的东西会起作用:
-- | 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
类型。
我正在通过一些 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)]
现在我想要这个函数,而不是告诉我集合中的一个元素具有多重性 1,而不是让它一个人呆着。因此,改为给出结果 [(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
子句有不同的类型,不幸的是你不能分段定义函数的(共同)域。我该如何解决这个问题?
BUT this doesn't work. I think because the then and else clauses have different types, and unfortunately you can't piece-wise define the (co)domain of your functions. How might I go about getting past this issue?
您的诊断是正确的; then
和 else
必须具有相同的类型。严格来说没有 "getting past this issue,"。无论您采用何种解决方案,都必须在条件的两个分支中使用相同的类型。一种方法是设计一个自定义数据类型来编码您想要的可能性,然后使用它。像这样的东西会起作用:
-- | 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
类型。