• Haskell stg Что-то у меня какое-то недопонимание partial apply: как оно вообще оказывается на уровне stg и откуда проблемы с неизвестной арностью функции? Происходят ли какие-то редукции при частичном применение и если да, то почему?

Replies (9)

  • @ndtimofeev, все частичное применение (у конструкторов) превращается в явные лямбды, если тебе это поможет
  • @ndtimofeev, Оказывается оно оттого, что нужно. Как ты реализовать хаскель-то будешь без этого? Ну хоть (1+) $ 2?
    Про проблему я не понимаю. $ закидывает на стек 2, потом вызывает замыкание 1+, который закидывает на стек 1 и вызывает +. Само замыкание не апдейтится при этом никак.
  • @rkit, В stg перепишу как замыкание let { inc = \x -> 1 + x; ap = \f v -> f v } in ap inc 2 и вроде бы никакого частичного применения не осталось.
  • @ndtimofeev, Нормальный полиморфизм а-ля (a -> b -> a) допускает, что a и b могут быть чем угодно, в том числе функциями неизвестной арности.
  • @balodja, Речь идёт о компиляции совсем-совсем полиморфного кода? Что-то вроде библиотечных функций которые можно сначало скомпилировать, а потом использовать на произвольных типах? Просто в ином случае всё это должно быть заинлайнено в компиляции и в stg попадёт замыкание.
  • @ndtimofeev, {+, ap} \u {} ->
    let
    inc = {+} -> \n {} -> (+) {1}
    in
    ap {inc, 2}
    Вот так оно транслируется в STG.


    Просто в ином случае всё это должно быть заинлайнено в компиляции и в stg попадёт замыкание.Частичное применение это и есть замыкание.
    А инлайн это дупликация кода и поэтому не должно быть заинлайнено, а должно быть очень аккуратно проанализировано на возможность инлайна.
  • @rkit, Просто тогда всё равно не понятно почему partial apply выскакивает на уровне stg. В том виде в котором оно есть в haskell это что-то вроде синтаксического сахара для явных замыканий.
  • @ndtimofeev, В том виде, в котором оно есть в хаскеле это фундаметальный элемент языка, с использованием которого написано вообще ВСЕ. И переписав это обратно в некаррированный стиль ты ничего не выиграешь, а только загрузишь себя проблемой оптимизацией лишнего перекладывания агрументов.
    (f 1) 2 —
    кладем 2 на стек
    вызываем (f 1)
    кладем 1 на стек
    вызываем +
    (\ x -> f 1 x) 2
    кладем 2 на стек
    вызываем (\ x -> f 1 x)
    снимаем 2 со стека
    кладем 2 на стек
    кладем 1 на стек
    вызываем +
  • @rkit, А при pap мы имеем что-то другое?