第一个问题:
定义一个函数,使用分隔符将列表中的所有列表连接在一起。
类型定义应该如下:
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
但是,正如您所看到的,它没有类型定义。
如果我将类型定义放在函数上面,我会得到一个错误。
为什么?
第二个问题:
在解决方案之前,我想在保护程序列表中添加另一个保护程序。
这个保护程序应该在第一个保护程序之后。
我想检查列表变量是否只有一个列表,所以我只返回列表变量。
但我不能像那样设置保护程序(同样,会出现错误:-)):
| lists == (x:[]) = lists
and also this didn't work:
| lists == (_:[]) = lists
why why why ? :-).
之后我尝试创建其他的守卫:
| length lists == 1 = lists
但它引发了一个错误。
顺便说一句,我不需要那些保护,因为我发现在“where”关键字后的第一个模式恰好是我想要的。
这就是我所说的模式:
attach myChar (x:[]) = x
但是,我仍然想了解为什么我尝试的保护没有起作用。 而且,我是通过运气找到这个解决方案的,我不认为每次都能注意到这样的事情:-)
非常感谢 :-)。
p.s. 这个练习来自书籍《Real World Haskell》。
intersperse sep = foldr1 (\i a -> i ++ sep : a)
。 - Chuck