我在Haskell从事这项工作,那里有一个元组列表,我们需要取消配对并将它们放入不同的列表中。
所需结果:
Main> unpair [(1,2),(3,4),(5,6)]
([1,3,5],[2,4,6])
我的代码,但出现一些错误:
unpair :: [(a,b)] -> ([a],[b])
unpair list = ([a|a<-list.fst], [b|b<-list.snd])
错误:
Template.hs:8:22:
Couldn't match expected type `b0 -> c0' with actual type `[(a, b)]'
Relevant bindings include
list :: [(a, b)] (bound at Template.hs:8:8)
unpair :: [(a, b)] -> ([a], [b]) (bound at Template.hs:8:1)
In the first argument of `(.)', namely `list'
In the expression: list . fst
Template.hs:8:22:
Couldn't match expected type `[a]'
with actual type `(b0, b1) -> c0'
Relevant bindings include
list :: [(a, b)] (bound at Template.hs:8:8)
unpair :: [(a, b)] -> ([a], [b]) (bound at Template.hs:8:1)
In the expression: list . fst
In a stmt of a list comprehension: a <- list . fst
In the expression: [a | a <- list . fst]
Template.hs:8:39:
Couldn't match expected type `b2 -> c1' with actual type `[(a, b)]'
Relevant bindings include
list :: [(a, b)] (bound at Template.hs:8:8)
unpair :: [(a, b)] -> ([a], [b]) (bound at Template.hs:8:1)
In the first argument of `(.)', namely `list'
In the expression: list . snd
Template.hs:8:39:
Couldn't match expected type `[b]'
with actual type `(a0, b2) -> c1'
Relevant bindings include
list :: [(a, b)] (bound at Template.hs:8:8)
unpair :: [(a, b)] -> ([a], [b]) (bound at Template.hs:8:1)
In the expression: list . snd
In a stmt of a list comprehension: b <- list . snd
In the expression: [b | b <- list . snd]
该问题还指出要尝试通过列表理解来做到这一点。
谢谢
答案 0 :(得分:3)
您的错误消息仅对此有所提示。您遇到的问题是您误用了.
运算符。在list.fst
调用fst
对象上的函数list
之前,您可能已经使用面向对象的语言进行编程。在Haskell中并非如此,其中.
是用于infix function两个功能的compose。
您真正想做的是从列表中选择一个元组,然后一次对这些元组应用fst
/ snd
。例如:
[fst a | a <- list]
您还可以使用模式匹配,并跳过fst
/ snd
音高计,但这是好是坏是有意见的:
[a | (a, _) <- list]
答案 1 :(得分:2)
您几乎是对的!您只是遇到了一些小错误:
list.fst
-在语法上是有效的,但是.
运算符在Haskell中的作用与在其他语言中不同。 fst
是一个函数,应这样使用-尝试将其应用于例如fst list
。fst
或snd
应用于list
之类的列表;由于Haskell是强类型语言,因此必须将这些函数应用于单个值,而不是列表。尝试将这些功能移至栏的左侧,例如要获取列表中的所有fst
值,请使用[fst a | a <- list]
,这意味着“对于a
中的每个值list
,将fst
应用于a
'。