Эквивалентные функции, дающие разные результаты интерпретатора

Предыстория: я исследую анонимную рекурсию, и я беру на себя задачу реализовать прелюдию без использования какой-либо именованной рекурсии, просто чтобы все это хорошо запомнилось мне. Я еще не совсем там, и по пути наткнулся на кое-что не связанное с этим, но все же интересное.

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]

Первые две функции кажутся мне почти одинаковыми, поэтому я полагаю, что мой вопрос просто «Что здесь происходит?»

6
задан Daniel Fischer 17 January 2012 в 00:41
поделиться