Haskell q类型的手动推导(在正文中指定)

Haskell q类型的手动推导(在正文中指定),haskell,types,ghci,unification,Haskell,Types,Ghci,Unification,我不明白为什么q的类型是ordt=>[t]->[a]而不是orda=>[a]->[a] q [] = [] q (x:xs) = q us ++ q ws where us = filter (<=x) xs ws = filter (>=x) xs q[]=[] q(x:xs)=qus++qws 其中us=过滤器(=x)xs 在哪些情况下,输入类型可能与输出不同 谢谢, Sebastián.在任何情况下,这意味着:函数永远不会有用 这实际上是“免费定理”的一

我不明白为什么
q
的类型是
ordt=>[t]->[a]
而不是
orda=>[a]->[a]

q [] = []
q (x:xs) = q us ++ q ws
  where us = filter (<=x) xs
        ws = filter (>=x) xs
q[]=[]
q(x:xs)=qus++qws
其中us=过滤器(=x)xs
在哪些情况下,输入类型可能与输出不同

谢谢,

Sebastián.

在任何情况下,这意味着:函数永远不会有用

这实际上是“免费定理”的一个很好的例子。显然,类型
Ord t=>[t]->[a]
没有多大意义,因为您可以生成类型
[a]
(您对
a
!)的唯一列表是空列表。这证明了
q
只能做两件事:

  • 返回
    []
  • 不终止(即,
事实上,前者就是发生的情况:在每个递归步骤中,您从输入列表中弹出一个元素,但您实际上从未在结果中包含这些元素中的任何一个。所以你总是以
[]
结束

如果您正确地实现了快速排序,您当然会将
x
带回到两个子列表之间,即

q (x:xs) = q us ++ [x] ++ q ws

在任何情况下,这意味着:函数永远不会有用

这实际上是“免费定理”的一个很好的例子。显然,类型
Ord t=>[t]->[a]
没有多大意义,因为您可以生成类型
[a]
(您对
a
!)的唯一列表是空列表。这证明了
q
只能做两件事:

  • 返回
    []
  • 不终止(即,
事实上,前者就是发生的情况:在每个递归步骤中,您从输入列表中弹出一个元素,但您实际上从未在结果中包含这些元素中的任何一个。所以你总是以
[]
结束

如果您正确地实现了快速排序,您当然会将
x
带回到两个子列表之间,即

q (x:xs) = q us ++ [x] ++ q ws

如果尝试使用此实现对列表进行排序,会发生什么情况?有一个很好的理由可以解释为什么它有这种类型。尝试执行
q[1,3,2]
,你能告诉我为什么会得到这样的输出吗?省略签名实际上会导致对错误的有用提示,而不是更令人困惑的错误的少数情况之一@bheklillr对于任何输入,输出都是[],这是因为在每一步中,您都会删除输入的第一个元素。@Seba,没错,我希望如果您看到这一点,它可能会给您一个线索,说明您的实现出了什么问题,虽然leftaroundabout已经提供了解决方案。如果您尝试使用此实现对列表进行排序,会发生什么?有一个很好的理由可以解释为什么它有这种类型。尝试执行
q[1,3,2]
,你能告诉我为什么会得到这样的输出吗?省略签名实际上会导致对错误的有用提示,而不是更令人困惑的错误的少数情况之一@bheklillr对于任何输入,输出都是[],这是因为在每个步骤中都删除了输入的第一个元素。@Seba,对了,我希望如果您看到了这一点,它可能会给您一个线索,说明您的实现出了什么问题,尽管leftaroundabout已经提供了解决方案。