• ятупой Haskell Жуйц, просто скажи мне, если мы вызываем функцию от 3-х аргументов с 4-мя — нас посылают в силу неудавшегося паттерн матчинга — так?
    А если так, то, жуйк, ШТО должно значить выделенное жирным запись в след. коде:

    myFoldl f z xs = foldr step id xs z
    where step x g a = g (f a x)

    foldr — функция от трех аргументов, а мы вызываем её от 4-х:
    step, id, xs, z

    ЧЗХ?

Replies (38)

  • @folex, id smth == smth
  • @Polaris, Хотя я смотрю на код и всё меньше понимаю, как он в принципе может компилироваться.
  • @Polaris, Я знаю, и что? Неужто запись
    foldr step id xs z
    превращается сначала в
    foldr step (id xs) z
    а затем в
    foldr step xs z
    ?!

    Это же БРЕД.
  • @Polaris, Но он компилируется, и более того — даже работает.
  • @folex, book.realworldhaskell.org Вот тут ищите по слову "myfoldl"
  • @folex, хм, возможно так:
    foldr a b c d == (foldr a b c) d
  • @folex, Prelude> :t (foldr (\x g a -> g ((*) a x)))
    (foldr (\x g a -> g ((*) a x)))
    :: Num a => (a -> t) -> [a] -> a -> t
    Ваш кэп.
  • @lexszero, Я тоже так это понимаю, но ЧТО это должно значить? foldr вернет нам некое число или строку — скаляр, короче, а мы возьмем и РЯДОМ НАПИШЕМ НУЛИК? Так что ли?
    Правда, я ничего не понимаю.

    Но ещё больше меня смущает сигнатура foldl:
    foldl :: (a -> b -> a) -> a -> [b] -> a
    Принимает три аргумента, и возвращает 3 значения, так? Но оно же возвращает цифру или строку, или там список ._.
  • @folex, Какой ещё нахуй скаляр? Замени b на (a -> c) и всё поймёшь.
  • @L29Ah, Прости, а что значит бэкслеш перед x? Я не распарсил
  • @folex, лямбда
  • @folex, Лямбда.
  • @lexszero, В каком смысле "лямбда" в смысле буква лямбда или анонимная функция?
  • @folex, Нагуглил. Второе, значит. Хмм-м
  • @folex, Ты понимаешь, что если аргумент функции у тебя имеет тот-же тип, что и возвращаемое значение, то арность возвращаемого значения будет равной таковой у аргумента?
  • @L29Ah, Prelude> :t id
    id :: a -> a
    Prelude> :t id (+)
    id (+) :: Num a => a -> a -> a
    Prelude> id (+) 1 2
    3

    КАК ЭТО РАБОТАЕТ У id ЖЕ ВСЕГО ОДИН АРГУМЕНТ КОКОКОКОКО
  • @L29Ah, Хм, если поставить перед обеими частями предложения слово "всегда", то понимаю, да.
  • @folex, функции всегда принимают один аргумент. всегда. и возвращают всегда тоже один. тип функции — это всегда dom -> cod

    можно рассматривать сигнатуру foldl как-то так: (a -> b -> a) -> (a -> ([b] -> a)); dom ~ (a -> b -> a) (т.е. аргумент — функция), cod ~ (a -> ([b] -> a)) (т.е. возвращаемое значение — тоже функция)
  • @L29Ah, Кажется, понял ._.
    Ебаная ленивота, huh?
  • @folex, Не ленивота, а карринг.
  • @L29Ah, Тяжело ._. Но вроде кое-как понял, спасибо!
  • @folex, касательно исходного вопроса — смотри:

    Prelude> let step x y z = y ((*) z x)

    Prelude> :t step
    step :: Num a => a -> (a -> t) -> (a -> t)

    Prelude> :t foldr
    foldr :: (a -> b -> b) -> b -> [a] -> b

    Prelude> :t foldr step
    foldr step :: Num a => (a -> t) -> [a] -> (a -> t)

    Prelude> :t foldr step id
    foldr step id :: Num t => [t] -> t -> t

    Prelude> :t foldr step id [1, 2, 3]
    foldr step id [1, 2, 3] :: Num t => t -> t

    Prelude> :t foldr step id [1, 2, 3] 1
    foldr step id [1, 2, 3] 0 :: Num t => t

    Prelude> foldr step id [1, 2, 3] 1
    6

    я там немного скобочек дорасставлял, чтобы понятней было,- какой тип куда подставляется. надеюсь, поможет
  • @jtootf, Не понимаю сигнатуру step ((
    Вот если бы читать её вслух, как бы она звучала?
  • @folex, Для всех чисел она делает из числа и функции из числа в говно функцию из числа в говно. Или для всех чисел она делает из числа, функции из числа в говно и ещё одного числа говно. Или ещё как. По вкусу.
  • @jtootf, Тогда я не понимаю, почему foldl возвращает лишь одно число ._.
    И ещё я не понимаю записи (a -> ([b] -> a))
    Это ведь функция, которая принимает нечто типа a, а возвращает (как бы) два значения: [b] и a?

    Аыы ._.
  • @folex, Возвращает функцию из [b] в a.
  • @folex, step — это функция, принимающая значение типа a и возвращающая функцию, которая принимает функцию типа (a -> t) и возвращает функцию, которая принимает значение типа a и возвращает значение типа t
  • @folex, тип a -> b это всегда функция. не два значения. два значения (произведение типов) — это кортеж, в типе записывается как (a, b)

    а все функции — от одного аргумента. любую сигнатуру вида a -> b -> c -> d -> e можно записать как a -> (b -> (c -> (d -> e)))
  • @folex, Функция отхватывает столько аргументов, сколько может проглотить. Остальные достаются результату вычисления этой функции, который тоже может быть функцией.
  • @masai, каррированная функция принимает только 1 аргумент, но я тебя понял ._.
  • @folex, Один, аргумент, все аргументы… Это просто разные точки зрения на одно и то же. Иногда я думаю так, а иногда этак. По ситуации, как удобнее. :)
  • @folex, некаррированная тоже. аргумент может быть элементом декартового произведения произвольного количества типов, но он будет один
  • @jtootf, Да ._.
  • @jtootf, Но это уже будет не тот один аргумент, о котором идёт речь при каррировании.
  • @masai, что значит — не тот? карировать декартово произведение типов аналогично никто не мешает:

    f :: (a, b) -> c -> d
    g :: a -> (b, c) -> d
  • @jtootf, Я про то, что (a, b) -> c — это не то же самое, что a -> b -> c.
  • @masai, не то же, однако между множествами функций первого и второго вида (в любой замкнутой категории) существует естественный изоморфизм

    вообще я уже несколько потерял нить разговора, честно говоря
  • @jtootf, Да и я, в общем, уже не помню, что имел в виду. :)