背景:我正在研究匿名递归,并且我正在接受实现前奏的挑战,而不使用任何命名递归,只是为了帮助它在我的脑海中很好地坐下来。我还没到那里,一路上我遇到了一些无关但仍然有趣的事情。等效函数产生不同的解释结果
map1 = \f -> \x -> if (tail x) == []
then [f (head x)]
else f (head x) : (map1 f (tail x))
map2 f x = if (tail x) == []
then [f (head x)]
else f (head x) : (map2 f (tail x))
map3 f (x:xs) = if xs == [] then [f x] else f x : (map3 f xs)
map4 f (x:[]) = [f x]
map4 f (x:xs) = f x : map4 f xs
GHC抱怨第一个,第二个是好的,第三个和第四个只是为了展示他们如何实现不同。
*Main> map1 (*2) [1..10]
<interactive>:1:15:
No instance for (Num())
arising from the literal `10'
Possible fix: add an instance declaration for (Num())
In the expression: 10
In the second argument of `map1', namely `[1 .. 10]'
In the expression: map1 (* 2) [1 .. 10]
*Main> map2 (*2) [1..10]
[2,4,6,8,10,12,14,16,18,20]
*Main> map3 (*2) [1..10]
[2,4,6,8,10,12,14,16,18,20]
*Main> map4 (*2) [1..10]
[2,4,6,8,10,12,14,16,18,20]
如果我向map1添加一个类型签名,那就很好。
map1 :: Eq a => (a -> b) -> [a] -> [b]
前两个函数看起来几乎相同的给我,所以我想我的问题很简单“这是怎么回事?”
我不确定您是否有以这种方式编写的具体原因。为什么不使用[]作为递归的基本情况而不是(x:[])?你的任何函数都不能用于空列表。 – 2012-01-17 01:17:10