Haskell中任意数量列表的并集

Haskell中任意数量列表的并集,haskell,Haskell,如何在Haskell中获得任意数量列表的并集。例如,我想要一个如下所示的函数: example1 = union' [1,2,3] [1,4] example2 = union' [1,2,3] [1,4] [2,6] example1 [1,2,3,4] example2 [1,2,3,4,6] Haskell中的函数只接受一个参数。“双参数”函数实际上是一个返回另一个函数的函数,该函数返回最终返回值。因此,函数无法接受数量可变的参数,因为这样一个函数的返回类型不会得到很好的定义 如果您想要

如何在Haskell中获得任意数量列表的并集。例如,我想要一个如下所示的函数:

example1 = union' [1,2,3] [1,4]
example2 = union' [1,2,3] [1,4] [2,6]
example1
[1,2,3,4]
example2
[1,2,3,4,6]

Haskell中的函数只接受一个参数。“双参数”函数实际上是一个返回另一个函数的函数,该函数返回最终返回值。因此,函数无法接受数量可变的参数,因为这样一个函数的返回类型不会得到很好的定义

如果您想要获得任意数量的列表的并集,那么您的函数应该获得列表的列表,因为列表可以包含任意数量的元素

union' :: Eq a => [[a]] -> [a]
union' = foldr unionOfTwo []
  where unionOfTwo :: Eq a => [a] -> [a] -> [a]
        unionOfTwo xs ys = ...  -- left as an exercise
其中,
unionOfTwo
知道如何计算两个列表的并集。实际上,
union'
将输入中的第一个列表放在一边,递归地计算剩余输入的并集,然后计算该结果与原始第一个列表的并集。换句话说,

union' []  = []
union' (xs:xss) = unionOfTwo xs (union' xss)

Haskell中的函数只接受一个参数。“双参数”函数实际上是一个返回另一个函数的函数,该函数返回最终返回值。因此,函数无法接受数量可变的参数,因为这样一个函数的返回类型不会得到很好的定义

如果您想要获得任意数量的列表的并集,那么您的函数应该获得列表的列表,因为列表可以包含任意数量的元素

union' :: Eq a => [[a]] -> [a]
union' = foldr unionOfTwo []
  where unionOfTwo :: Eq a => [a] -> [a] -> [a]
        unionOfTwo xs ys = ...  -- left as an exercise
其中,
unionOfTwo
知道如何计算两个列表的并集。实际上,
union'
将输入中的第一个列表放在一边,递归地计算剩余输入的并集,然后计算该结果与原始第一个列表的并集。换句话说,

union' []  = []
union' (xs:xss) = unionOfTwo xs (union' xss)

首先是一个工作代码示例:

{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
module Main where
import Data.List (union)

class Unionable a t where
  union' :: [a] -> t

instance  Unionable a [a] where
  union' = id

instance  (Eq a, Unionable a t) => Unionable a ([a] -> t) where
  union' xs ys = union' (union xs ys)

main = do
  print $ (union' [1::Integer,2,3] [1::Integer,5,6] [1::Integer,7,3] :: [Integer])
模仿

您可能希望将这样一个函数用于文本,不幸的是,正如您在这里看到的,将它用于多态文本并不方便,因为您需要指定每个参数的类型

在其他上下文中,参数的类型必须清楚,结果的预期类型也必须清楚,否则,您将需要添加此类类型注释

对于普通代码来说,这可能不值得付出努力

让我们解释一下这里发生了什么,编译器看到:

(union' [1::Integer,2,3] [1::Integer,5,6] [1::Integer,7,3] :: [Integer])
它认为,我们需要

union' :: [Integer] -> [Integer] -> [Integer] -> [Integer]
我们有这样的工会吗?第二审声明将提供这方面的候选人

a ~ Integer
t ~ [Integer] -> [Integer] -> [Integer]
但是为了使该实例适用,我们需要一个带有这些赋值的
(Unionable a t)
实例。我们有这样的例子吗?第二个实例声明也是一个候选者,这次是

a ~ Integer
t ~ [Integer] -> [Integer]
a ~ Integer
t ~ [Integer]
但是为了使该实例适用,我们需要一个带有这些赋值的
(Unionable a t)
实例。我们有这样的例子吗?第二个实例声明也是一个候选者,这次是

a ~ Integer
t ~ [Integer] -> [Integer]
a ~ Integer
t ~ [Integer]
这一次,我们从带有 不需要额外的限制

这意味着(为了清晰起见,匹配类型注释)


首先是一个工作代码示例:

{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
module Main where
import Data.List (union)

class Unionable a t where
  union' :: [a] -> t

instance  Unionable a [a] where
  union' = id

instance  (Eq a, Unionable a t) => Unionable a ([a] -> t) where
  union' xs ys = union' (union xs ys)

main = do
  print $ (union' [1::Integer,2,3] [1::Integer,5,6] [1::Integer,7,3] :: [Integer])
模仿

您可能希望将这样一个函数用于文本,不幸的是,正如您在这里看到的,将它用于多态文本并不方便,因为您需要指定每个参数的类型

在其他上下文中,参数的类型必须清楚,结果的预期类型也必须清楚,否则,您将需要添加此类类型注释

对于普通代码来说,这可能不值得付出努力

让我们解释一下这里发生了什么,编译器看到:

(union' [1::Integer,2,3] [1::Integer,5,6] [1::Integer,7,3] :: [Integer])
它认为,我们需要

union' :: [Integer] -> [Integer] -> [Integer] -> [Integer]
我们有这样的工会吗?第二审声明将提供这方面的候选人

a ~ Integer
t ~ [Integer] -> [Integer] -> [Integer]
但是为了使该实例适用,我们需要一个带有这些赋值的
(Unionable a t)
实例。我们有这样的例子吗?第二个实例声明也是一个候选者,这次是

a ~ Integer
t ~ [Integer] -> [Integer]
a ~ Integer
t ~ [Integer]
但是为了使该实例适用,我们需要一个带有这些赋值的
(Unionable a t)
实例。我们有这样的例子吗?第二个实例声明也是一个候选者,这次是

a ~ Integer
t ~ [Integer] -> [Integer]
a ~ Integer
t ~ [Integer]
这一次,我们从带有 不需要额外的限制

这意味着(为了清晰起见,匹配类型注释)


Haskell中的变量函数不能在不经过很多限制的情况下实现。相反,您应该定义<代码>联合::[EQA] > [A] > [A] < /COD>,并将列表的单个列表作为参数。考虑“<代码>联合”[1,2,3] [1,4] < /代码>的类型:它是一个列表,或者它是一个函数,您可以应用到<代码> [2,6] < /代码>?我认为 Union < <代码>将是一个列表,但我完全不懂用Haskell编码,所以不要相信我的话。我需要得到任意数量的数字列表的并集,然后将列表中的所有数字相加。关于如何创建
union'
函数,您有什么建议吗?因为我完全迷路了?模块简化了工作<代码>收费表。工会$Data.List.map fromList[[1,2,3,3,4],[2,2,3,4,4,5,6],[4,5,5,6,6,7]将返回
[1,2,3,4,5,6,7]
@K.Claesson这就是问题所在。如果它是一个列表,则不能调用其他值。如果它是一个函数,则不能将其视为列表。“解决方案”都涉及由既不是列表也不是函数的类型实现的类型类,这就是为什么您应该在Haskell中做惯用的事情,并且只关心接受列表列表而不是任意数量列表的函数。(严格地说,Haskell中的每个函数都接受一个参数;像unionOfTwo::Eq a=>[a]->[a]->[a]这样的函数接受一个参数,并返回一个接受一个参数的函数。)Haskell中的可变函数无法实现