Ошибка, которую вы отправили, не исходит из вашего определения myMap
, это исходит из того, как вы ее используете. Тип первого myMap
- ([a] -> [a]) -> [a] -> [a]
, который не соответствует типу Prelude.map
. Во втором вы заменили имена переменных, а также тот, который вы применяете f
. Компилятору все равно, что вы называете аргументами в вашей лямбда, переданной в foldr
, поэтому foldr (\x acc -> f x : acc)
идентичен foldr (\foo bar -> f foo : bar)
. Это может быть то, что вас трогает.
Второй работает, потому что (просто) это правильно. В первом вы подаете f
в свой список аккумуляторов x
(хотя у вас есть переменная с именем acc
, это не ваш аккумулятор), поэтому f
должен взять список и вернуть список. Во втором вы применяете f
к каждому элементу, а затем добавляете это в свой список аккумуляторов. Если у вас myMap (+1)
, он будет иметь тип
myMap (+1) :: Num [a] => [a] -> [a]
Который говорит, что вы должны передать ему список значений [a]
где [a]
реализует Num
, и в настоящее время не существует ни одного случая для Num [a]
, не будет ли когда-нибудь.
TL; DR: В первом случае вы применяете свою отображаемую функцию в свой список аккумуляторов, а во втором вы применяете сопоставленную функцию к каждому элементу.
В качестве полезного упражнения вы можете попробовать развернуть 'map (+10) [1,2]' with оба определения и заметить, что первый не работает и, возможно, понимает, что с ним не так. – chi