Немного неофитный вопрос haskell, но я наткнулся на этот пример в примеры учебников Haskell. Для "найти последний элемент списка" есть несколько очевидных версий, например
last' [x] = x
last' (_:xs) = last' xs
Но я не могу понять представленную альтернативную версию:
myLast' = foldr1 (const id)
Итак, пытаясь понять, что делает приложение функции id, я попробовал в ghci:
const id 1 2 -> gives 2
Это связывается так:
(const id) 1 2 -> gives 2
А не так:
const (id 1) 2 -> gives 1
Но я не понимаю этого. (const id) должен переводиться примерно так:
`(\x y->x) (\x->x)`
Разве это не должно возвращать функцию, которая просто возвращает идентификатор своего первого элемента? Или как создание порядка функций (const id) отличается от const?
Хочу поблагодарить академию, моего продюсера, режиссера ....





Определение const:
const x = \_ -> x
Следовательно, (const id) - это функция, которая принимает один аргумент и всегда возвращает id и
const id 1 2 = (\_ -> id) 1 2
= id 2
= 2
Определение foldr1:
foldr1 f [x] = x
foldr1 f (x:xs) = f x (foldr1 f xs)
Если у нас есть
myLast' = foldr1 (const id)
потом
myLast' [x] = foldr1 (const id) [x]
{- definition of foldr1 -}
= x
и
myLast' (x:xs) = foldr1 (const id) (x:xs)
{- definition of foldr1 -}
= (const id) x (foldr1 (const id) xs)
{- definition of const -}
= (\_ -> id) x (foldr1 (const id) xs)
{- function application -}
= id (foldr1 (const id) xs)
{- definition of id -}
= foldr1 (const id) xs
{- definition of myLast' -}
= myLast' xs
что согласуется с определением last'.
аааа. Не подключил константу, возвращающую функцию. Спасибо за объяснение.
Это отличное объяснение, и, пройдя его, я могу понять, как оно работает. Но действительно ли foldr1 (const id) идиоматический способ выполнить функцию myLast? Первый приведенный пример кажется более ясным ...
Я бы не сказал, что это идиоматично ... Вундеркинды Haskell любят работать над тем, как выражать вещи в «безточечном» стиле или просто в терминах складок. Это становится своего рода головоломкой программирования. Первая версия намного понятнее.
Я сильно полагаюсь на :t, когда пытаюсь понять Haskell. В этом случае:
Prelude> :t const id
const id :: b -> a -> aмог бы помочь вам понять, что происходит.
Чтобы уточнить, ": t" - это команда, которую вы можете использовать в GHCI для печати типа выражения.
Добро пожаловать в клуб 10k!