List 函数式编程中的列表,更具体地说是Haskell中的列表
我正在研究Haskell,看到了这个问题:List 函数式编程中的列表,更具体地说是Haskell中的列表,list,function,haskell,functional-programming,List,Function,Haskell,Functional Programming,我正在研究Haskell,看到了这个问题: h [] = [] h [x] = [] h (x:y:ys) = (x <= y): (h (y:ys)) h[]=[] h[x]=[] h(x:y:ys)=(x 第三个条件h(x:y:ys)=(x)是什么 第三个条件是什么h(x:y:ys)=(xh的完整类型是orda=>[a]->[Bool] 前两个等式意味着输入和输出都是某种类型的列表。对于我们的第一个过程,我们将假设h::[a]->[b];接下来我们将找出a和b上的约束(如果有) 第
h [] = []
h [x] = []
h (x:y:ys) = (x <= y): (h (y:ys))
h[]=[]
h[x]=[]
h(x:y:ys)=(x
第三个条件h(x:y:ys)=(x)是什么
第三个条件是什么h(x:y:ys)=(xh
的完整类型是orda=>[a]->[Bool]
前两个等式意味着输入和输出都是某种类型的列表。对于我们的第一个过程,我们将假设h::[a]->[b]
;接下来我们将找出a
和b
上的约束(如果有)
第三个等式中输入列表中的前两个值由(a->a->Bool
使用,因此我们现在知道输入列表必须是Ord a=>[a]
此外,根据([a]->[a]
的结果,我们知道h
必须返回[Bool]
类型的值
h
的完整类型是orda=>[a]->[Bool]
前两个等式意味着输入和输出都是某种类型的列表。对于我们的第一个过程,我们将假设h::[a]->[b]
;接下来我们将找出a
和b
上的约束(如果有)
第三个等式中输入列表中的前两个值由(a->a->Bool
使用,因此我们现在知道输入列表必须是Ord a=>[a]
此外,根据([a]->[a]
的结果,我们知道h
必须返回[Bool]
类型的值
您可以将函数重写为hs=zipWith(@Taren:不完全是因为原始h
将返回空列表的[]
,而您的定义将崩溃。但我承认这是一个细节:)。@WillemVanOnsem实际上,如果s为空(tail s)从来都没有计算过,而且效果很好!都是因为懒惰或其他原因。@Taren:你在这里运行的是未定义的行为:)。这与懒惰本身无关,而是第一个操作数首先被计算。你可以编写一个zip
函数,首先验证第二个操作数:)例如zipWith f[]=[]
,zipWith f[].[]
,zipWith f(x:xs)(y:ys)=(f x y):zipWith f xs ys
可能失败:)@WillemVanOnsem不是真的未定义:给出了zipWith的规范。您的定义不兼容。您可以将函数重写为hs=zipWith(@Taren:不完全是因为原始的h
将返回空列表的[]
,而您的定义将崩溃。但我承认这是一个细节:)@WillemVanOnsem实际上,如果s是空的(tail s),它永远不会被计算,并且工作正常!这一切都是因为懒惰或其他原因。@Taren:好吧,您在未定义的行为中运行:)。它与懒惰本身无关,而是首先计算第一个操作数。可以编写一个zip
函数,首先验证第二个操作数:)例如zipWith f.[]=[]
,zipWith f[].[]
,zipWith f(x:xs)(y:ys)=(f x y):zipWith f xs ys
可能失败:)@WillemVanOnsem并非真正未定义:提供了zipWith的规范。您的定义将不兼容。
h (x:(y:ys)) = (x <= y): (h (y:ys))