Haskell格式问题
我是haskell编程的初学者,经常会出错Haskell格式问题,haskell,format,Haskell,Format,我是haskell编程的初学者,经常会出错 xxx.hs:30:1: parse error on input `xxx' 通常会有一点玩弄解决方案的格式。这是相同的代码,看起来也一样,但在玩过之后,错误就消失了 目前我已经知道了错误 LookupAll.hs:30:1: parse error on input `lookupAll' 在该代码之后: lookupOne :: Int -> [(Int,a)] -> [a] lookupOne _ [] = [] lookupO
xxx.hs:30:1: parse error on input `xxx'
通常会有一点玩弄解决方案的格式。这是相同的代码,看起来也一样,但在玩过之后,错误就消失了
目前我已经知道了错误
LookupAll.hs:30:1: parse error on input `lookupAll'
在该代码之后:
lookupOne :: Int -> [(Int,a)] -> [a]
lookupOne _ [] = []
lookupOne x list =
if fst(head list) == x then snd(head list) : []
lookupOne x (tail list)
-- | Given a list of keys and a list of pairs of key and value
-- 'lookupAll' looks up the list of associated values for each key
-- and concatenates the results.
lookupAll :: [Int] -> [(Int,a)] -> [a]
lookupAll [] _ = []
lookupAll _ [] = []
lookupAll xs list = lookupOne h list ++ lookupAll t list
where
h = head xs
t = tail xs
但在我看来,我做的一切都是对的。没有标签之类的东西。始终为4个空格。这个问题有一个通用的解决方案吗?我现在正在使用记事本+
谢谢 问题不在于
lookupAll
,而在于前两行代码
if fst (head list) == x then snd (head list) : []
lookupOne x (tail list)
此if语句中没有包含else
。我猜你的意思是
if fst (head list) == x then snd (head list) : []
else lookupOne x (tail list)
我个人更愿意将其格式化为
if fst (head list) == x
then snd (head list) : []
else lookupOne x (tail list)
但这是品味的问题
如果您想积累一个符合条件的值列表,有几种方法。到目前为止,最简单的方法是使用
过滤器
,但也可以使用显式递归。要使用过滤器
,您可以将函数编写为
lookupOne x list
= map snd -- Return only the values from the assoc list
$ filter (\y -> fst y == x) list -- Find each pair whose first element equals x
如果您想使用递归,可以将其编写为
lookupOne _ [] = [] -- The base case pattern
lookupOne x (y:ys) = -- Pattern match with (:), don't have to use head and tail
if fst y == x -- Check if the key and lookup value match
then snd y : lookupOne x ys -- If so, prepend it onto the result of looking up the rest of the list
else lookupOne x ys -- Otherwise, just return the result of looking up the rest of the list
这两者是等价的。实际上,您可以将过滤器实现为
filter cond [] = []
filter cond (x:xs) =
if cond x
then x : filter cond xs
else filter cond xs
map f [] = []
map f (x:xs) = f x : map f xs
lookupOne x list = mapFilter snd (\y -> fst y == x) list
和map
as
filter cond [] = []
filter cond (x:xs) =
if cond x
then x : filter cond xs
else filter cond xs
map f [] = []
map f (x:xs) = f x : map f xs
lookupOne x list = mapFilter snd (\y -> fst y == x) list
希望您可以发现<代码>过滤器> />代码>代码> LoopUnn>代码>,并使用<代码> MAP>代码>考虑<代码> f==SND ,因此,在代码< > LoopUnON/CODE>的显式递归版本中,合并了两个模式:<代码> MAP>代码>和<代码>过滤器>代码>。你可以把这个组合模式推广到一个高阶函数中
mapFilter :: (a -> b) -> (a -> Bool) -> [a] -> [b]
mapFilter f cond [] = []
mapFilter f cond (x:xs) =
if cond x
then f x : mapFilter f cond xs
else : mapFilter f cond xs
您可以使用它来实现lookupOne
as
filter cond [] = []
filter cond (x:xs) =
if cond x
then x : filter cond xs
else filter cond xs
map f [] = []
map f (x:xs) = f x : map f xs
lookupOne x list = mapFilter snd (\y -> fst y == x) list
或者更简单地说
lookupOne x = mapFilter snd ((== x) . fst)
问题不在于lookupAll
,而在于前两行代码
if fst (head list) == x then snd (head list) : []
lookupOne x (tail list)
此if语句中没有包含else
。我猜你的意思是
if fst (head list) == x then snd (head list) : []
else lookupOne x (tail list)
我个人更愿意将其格式化为
if fst (head list) == x
then snd (head list) : []
else lookupOne x (tail list)
但这是品味的问题
如果您想积累一个符合条件的值列表,有几种方法。到目前为止,最简单的方法是使用过滤器
,但也可以使用显式递归。要使用过滤器
,您可以将函数编写为
lookupOne x list
= map snd -- Return only the values from the assoc list
$ filter (\y -> fst y == x) list -- Find each pair whose first element equals x
如果您想使用递归,可以将其编写为
lookupOne _ [] = [] -- The base case pattern
lookupOne x (y:ys) = -- Pattern match with (:), don't have to use head and tail
if fst y == x -- Check if the key and lookup value match
then snd y : lookupOne x ys -- If so, prepend it onto the result of looking up the rest of the list
else lookupOne x ys -- Otherwise, just return the result of looking up the rest of the list
这两者是等价的。实际上,您可以将过滤器实现为
filter cond [] = []
filter cond (x:xs) =
if cond x
then x : filter cond xs
else filter cond xs
map f [] = []
map f (x:xs) = f x : map f xs
lookupOne x list = mapFilter snd (\y -> fst y == x) list
和map
as
filter cond [] = []
filter cond (x:xs) =
if cond x
then x : filter cond xs
else filter cond xs
map f [] = []
map f (x:xs) = f x : map f xs
lookupOne x list = mapFilter snd (\y -> fst y == x) list
希望您可以发现<代码>过滤器> />代码>代码> LoopUnn>代码>,并使用<代码> MAP>代码>考虑<代码> f==SND ,因此,在代码< > LoopUnON/CODE>的显式递归版本中,合并了两个模式:<代码> MAP>代码>和<代码>过滤器>代码>。你可以把这个组合模式推广到一个高阶函数中
mapFilter :: (a -> b) -> (a -> Bool) -> [a] -> [b]
mapFilter f cond [] = []
mapFilter f cond (x:xs) =
if cond x
then f x : mapFilter f cond xs
else : mapFilter f cond xs
您可以使用它来实现lookupOne
as
filter cond [] = []
filter cond (x:xs) =
if cond x
then x : filter cond xs
else filter cond xs
map f [] = []
map f (x:xs) = f x : map f xs
lookupOne x list = mapFilter snd (\y -> fst y == x) list
或者更简单地说
lookupOne x = mapFilter snd ((== x) . fst)
我认为@bheklillr是对的-您缺少了一个或
但是,您可以通过将lookupOne
形成函数组合,而不是编写自己的新递归函数,来解决这个特定的格式问题
例如,您可以通过如下定义lookupOne
来获得正确的行为:
lookupOne a = map snd . filter ((==) a . fst)
通过这种方式,更清楚的是,您首先过滤掉输入列表中元组的第一个元素与键匹配的元素,然后只提取每个元组的第二个元素。我认为@bheklir是正确的-您缺少了一个或
但是,您可以通过将lookupOne
形成函数组合,而不是编写自己的新递归函数,来解决这个特定的格式问题
例如,您可以通过如下定义lookupOne
来获得正确的行为:
lookupOne a = map snd . filter ((==) a . fst)
这样就更清楚了,您首先要过滤掉输入列表中元组的第一个元素与键匹配的元素,然后只提取每个元组的第二个元素。您忘记了else
子句不是Haskell中if
表达式的可选部分。您忘记了else
子句不是Haskell中if
表达式的可选部分。首先,我使用了“else”,但这不是我想要的代码。因为问题不做它必须做的事情:D我需要它而不需要“else”。如果是xxx,那么xxx和than总是yyy。你知道我的意思吗?但你是对的。对于“else undefined”,编译代码不会出错。@fuuman是否要累积要返回的值列表?如果是这样的话,那就不是这样做的。在Haskell中,计算一个值(snd(head list):[]
)是没有意义的,然后扔掉该值,再计算另一个值(lookupOne x(tail list)
)。所有表达式都返回一个值,并且该值必须是静态类型。这就是代码应该做的:lookupAll[1,2][(1,“Koblenz”),(1,“Koblenz”)]~=[“Koblenz”,“Koblenz”],[1,1][(1,“Koblenz”)]~=[“Koblenz”,“Koblenz”],在查找之前的else中有:;##失败:lookupAll:1应为:[“Koblenz”,“Koblenz”]但是得到:[“科布伦茨”]。。。。在其他语言中,您只能在不需要其他语言的情况下编写。但是编译器给了我一个错误,所以我需要这里的else。所以我需要一个cmd,它不做任何我想做的事情。我没有遍历第一个值。我把它保存在列表中。之后,我重新启动了我的函数。感谢每次我带着我的代码问题来到这个网站时所付出的巨大努力。这个网站很棒!感谢所有的回答,特别是贝克利尔的所有解释!:-)首先,我用了“else”,但那不是我想要的代码。因为问题不做它必须做的事情:D我需要它而不需要“else”。如果是xxx,那么xxx和than总是yyy。你知道我的意思吗?但你是对的。用一个“else”