第一个问题:
定义一个使用分隔符值将列表连接在一起的函数。
类型定义应该是这样的:
intersperse :: a -> [[a]] -> [a]分隔符应该出现在列表的元素之间,但不应该紧跟在最后一个元素之后。
您的函数应如下所示:
ghci> :load Intersperse
[1 of 1] Compiling Main ( Intersperse.hs, interpreted )
Ok, modules loaded: Main.
ghci> intersperse ',' []
""
ghci> intersperse ',' ["foo"]
"foo"
ghci> intersperse ',' ["foo","bar","baz","quux"]
"foo,bar,baz,quux"过了一段时间,我设法解决了这个问题:
intersperse myChar lists
| lists == [] = ""
| otherwise = attach myChar lists
where attach myChar (x:[]) = x
attach myChar (x:xs) = x ++ (myChar : []) ++ attach myChar xs 但是,如您所见,它没有类型定义。
如果我把类型定义放在函数上面,我会得到一个错误。为什么?
第二个问题:
在我得到这个解决方案之前,我想在保安列表中添加另一个保安。这个quard应该在第一个守卫之后。我想检查列表变量中是否只有一个列表,所以我只返回列表变量。但我不能做这样的守卫(再说一次,错误来了:-):
| lists == (x:[]) = lists而且这也不起作用:
| lists == (_:[]) = lists为什么?:-)。
在这之后,我试着做其他的守卫:
| length lists == 1 = lists但它也引发了一个错误。
(顺便说一下,我不需要这些保护,因为我发现"where“关键字后的第一个模式正是我想要的。
这是我想说的模式:
attach myChar (x:[]) = x但是,我仍然想知道为什么我尝试的quards不起作用。另外,幸运的是,我找到了这个解决方案,我不认为每次我都会注意到这样的事情:-)
非常感谢:-)。
附注:本练习来自real world haskell一书。
发布于 2010-01-13 22:12:16
""的类型是[Char],但是你的类型签名说intersperse返回一个[a],而a依赖于输入类型,所以类型不匹配。为了这个守卫
|长度列表== 1=列表
lists的类型为[[a]],但您应该返回一个[a]。也就是说,如果lists为["foo"],则需要返回"foo"。您不希望返回["foo"].
发布于 2010-01-13 22:13:57
问题是你的函数不是泛化的,它只适用于字符串(字符列表)。如果您将第二行更改为
lists == [] = []您将得到您想要的东西,尽管由于等于运算符而依赖于Eq类型类。它甚至适用于字符串,因为所有的字符串也是列表,但并不是所有的列表都是字符串。
顺便说一下,您可以通过使用模式匹配进一步泛化您的函数:
intersperse myChar lists = case lists of
[] -> []
lists -> attach myChar lists
where attach myChar (x:[]) = x
attach myChar (x:xs) = x ++ (myChar : []) ++ attach myChar xs 或者,更地道地说:
intersperse _ [] = []
intersperse x xs = attach x xs
where attach myChar (x:[]) = x
attach myChar (x:xs) = x ++ (myChar : []) ++ attach myChar xs并摆脱了内部函数:
intersperse _ [] = []
intersperse _ (xs:[]) = xs
intersperse x (xs:xss) = (xs ++ x:intersperse x xss)关于第二个问题,您在卫士中使用的equals运算符需要两端都有值。你不能和它进行模式匹配。也许您正在寻找的是类似于这里的第二次改进。
发布于 2010-01-13 22:36:27
这会引发一个错误。
为什么?它和你做的一样,除了你用case of写的。
intersperse :: a -> [[a]] -> [a]
intersperse myChar lists
| lists == [] = []
| otherwise = attach myChar lists
where attach myChar (x:[]) = x
attach myChar (x:xs) = x ++ (myChar : []) ++ attach myChar xs这不会引发错误(这是您所建议的):
intersperse :: a -> [[a]] -> [a]
intersperse myChar lists = case lists of
[] -> []
lists -> attach myChar lists
where attach myChar (x:[]) = x
attach myChar (x:xs) = x ++ (myChar : []) ++ attach myChar xs
但是在我的示例中(这里的第一个函数),我按照您的建议更改了防护,但仍然得到一个错误。
为什么会这样呢?
非常感谢。
https://stackoverflow.com/questions/2057093
复制相似问题