Haskell中的连接和与AList的混淆([a]->;[a])

Haskell中的连接和与AList的混淆([a]->;[a]),list,haskell,functional-programming,concatenation,lambda-calculus,List,Haskell,Functional Programming,Concatenation,Lambda Calculus,我有一个项目,我们正在提高Haskell中连接列表的速度。 我是Haskell的新手,对列表([a]->[a])特别是如何将我的AppendedList转换为常规列表感到困惑。任何帮助都将不胜感激 newtype AppendedList a = AList ([a] -> [a]) -- List[5] is represented as AList (\x -> 5:x) -- This function takes an argument and returns the A

我有一个项目,我们正在提高Haskell中连接列表的速度。 我是Haskell的新手,对列表([a]->[a])特别是如何将我的AppendedList转换为常规列表感到困惑。任何帮助都将不胜感激

newtype AppendedList a = AList ([a] -> [a])

-- List[5] is represented as AList (\x -> 5:x) 
-- This function takes an argument and returns the AppendedList for that 
single :: a -> AppendedList a
single m = AList (\x -> m : x)


-- converts AppendedList to regular List
toList :: AppendedList a -> [a]
toList = ???

最难的是不要直接给你答案:)

如果您还记得列表是如何在Haskell中构造的:
[1,2,3]=1:2:3:[]
,其中
[]
空列表

现在,让我们“遵循类型”(我们也将此思维过程称为类型驱动开发的TDD),看看您手头上有什么:

toList::附录列表a->[a]
toList(列表函数)=???
listFunction
的类型为
[a]->[a]
。因此,您需要向它提供一个多态列表(即任何类型的列表),以便它返回一个列表

你所知道的任何类型的的唯一列表是什么?将此列表传递给
listFunction
,所有内容都将编译,这是一个很好的指示器,表明它可能是正确的:D


我希望这在不提供简单答案的情况下有所帮助(目标是让你学习!)。

最困难的部分是不要直接给你答案:)

如果您还记得列表是如何在Haskell中构造的:
[1,2,3]=1:2:3:[]
,其中
[]
空列表

现在,让我们“遵循类型”(我们也将此思维过程称为类型驱动开发的TDD),看看您手头上有什么:

toList::附录列表a->[a]
toList(列表函数)=???
listFunction
的类型为
[a]->[a]
。因此,您需要向它提供一个多态列表(即任何类型的列表),以便它返回一个列表

你所知道的任何类型的的唯一列表是什么?将此列表传递给
listFunction
,所有内容都将编译,这是一个很好的指示器,表明它可能是正确的:D


我希望这能在不提供简单答案的情况下有所帮助(目标是让您学习!)。

附录a
是一种类型

f
是该类型的数据,其中包含一些函数
f::[a]->[a]
“内部”

f
是从列表到具有相同类型元素的列表的函数

我们可以用
some\u list::[a]
调用它,以获得
结果列表::[a]

f           :: [a] -> [a]
  some_list :: [a]
-------------------------
f some_list ::        [a]

resulting_list ::     [a]
resulting_list = f some_list 
我们也可以将
结果列表
用作
某些列表
,即

resulting_list = f resulting_list
因为它有相同的类型,这符合
f
的期望(也因为Haskell的懒惰)。因此

这是一个可能的定义。有了它

take 2 (toList (single 5))
将返回
[5,5]


编辑:当然
[5,5]
不是包含单个5的列表。此外,
take 4…
将返回
[5,5,5]
,因此我们的表示包含任意数量的五,而不仅仅是其中一个。但是,它只包含一个不同的数字5

这让人想起列表的两个应用程序函子实例,即
[]
ZipList
pure 5::[]Int实际上只包含一个5,但是
pure 5::ZipList Int
包含任意数量的5,但只包含5。当然,要添加无限的列表是很困难的,所以这里主要是出于好奇。值得思考的东西


在任何情况下,它都表明在这里输入检查代码的方法不止一种。这里有不止一份清单供我们使用。最简单的一个确实是
[]
,但另一个是。。。。我们的名单本身

附录列表a
是一种类型

f
是该类型的数据,其中包含一些函数
f::[a]->[a]
“内部”

f
是从列表到具有相同类型元素的列表的函数

我们可以用
some\u list::[a]
调用它,以获得
结果列表::[a]

f           :: [a] -> [a]
  some_list :: [a]
-------------------------
f some_list ::        [a]

resulting_list ::     [a]
resulting_list = f some_list 
我们也可以将
结果列表
用作
某些列表
,即

resulting_list = f resulting_list
因为它有相同的类型,这符合
f
的期望(也因为Haskell的懒惰)。因此

这是一个可能的定义。有了它

take 2 (toList (single 5))
将返回
[5,5]


编辑:当然
[5,5]
不是包含单个5的列表。此外,
take 4…
将返回
[5,5,5]
,因此我们的表示包含任意数量的五,而不仅仅是其中一个。但是,它只包含一个不同的数字5

这让人想起列表的两个应用程序函子实例,即
[]
ZipList
pure 5::[]Int实际上只包含一个5,但是
pure 5::ZipList Int
包含任意数量的5,但只包含5。当然,要添加无限的列表是很困难的,所以这里主要是出于好奇。值得思考的东西


在任何情况下,它都表明在这里输入检查代码的方法不止一种。这里有不止一份清单供我们使用。最简单的一个确实是
[]
,但另一个是。。。。我们的名单本身

查看差异列表。可以尝试定义
empty::AppendedList a
append::a->AppendedList a->AppendedList a
以便
append 5 empty==single 5
。查看差异列表。可以尝试定义
empty::AppendedList a
append::a->AppendedList a->AppendedList a
,这样
Append5 empty==single 5
。我投了反对票。虽然这里的提示将导致代码进行类型检查,甚至运行并执行某些操作,但它所导致的行为几乎肯定不是预期的。差异列表是一种真正的标准技术,几乎可以肯定设置此练习的人的目的(特别是在