Что бред? Вот у тебя программа, в ней надо работать со списками - мапать/зипать и т.п., в каком-нибудь хаскеле у тебя зоопарк из десятка ф-й, криво и неудобно, в лиспе одна map - красиво и удобно. Чего тут еще?
Что бред? Вот у тебя программа, в ней надо работать со списками - мапать/зипать и т.п., в каком-нибудь хаскеле у тебя зоопарк из десятка ф-й, криво и неудобно, в лиспе одна map - красиво и удобно. Чего тут еще?
у меня в haskell для работы со списками только map который $\equiv$ fmap, про какой зоопарк ты говоришь я затрудняюсь представить.
Ну ты писал что автоматизация верификации это якобы круто, но не написал ни одного аргумента, почему это круче, чем руками. есть все основания полагать, что руками быстрее и менее затратно. Так что вопрос нетривиальный.
Не совсем понял, что тут разворачивать. В лиспе у тебя просто функция map, а в хаскеле надо еще и zipWith городить, чтобы добатиься того же функционала, что содержит лисповый map.
но не написал ни одного аргумента, почему это круче, чем руками.
А зачем вообще нужна автоматизация каких-то процессов? Считали бы себе на арифмометрах.
руками быстрее и менее затратно
Вы, просто поглядев на чужой код, сразу же можете определить, где в нём гонка? Тогда вам это действительно не нужно. К сожалению, ни я, ни мои знакомые, всецело занимающиеся параллельными алгоритмами, такой способностью не обладают.
А зачем вообще нужна автоматизация каких-то процессов? Считали бы себе на арифмометрах.
Она нужна для экономии трудозатрат. Но в каждом случае следует отдельно обосновывать, что овчинка стоит выделки.
Проблема то в чем - если бы у нас автоматически распараллеливался обычный код, то цены бы этому не было. Но ведь не получается - надо писать код специальным особым образом, в IO, с нотациями для компилятора о том как и что параллелить можно и как - нельзя. И вполне вероятно, что затраты на такое «особое» написание кода окажутся значительно выше, чем затраты на автоматическое распараллеливание (обратное никто не доказал).
Кроме того, вот есть те же акторы или параллельные коллекции - и они спокойно работают несмотря на то, что компилятор об отсутствии сайд-эффектов не знает. Вообще, компилятор в этом плане может быть весьма оптимистичным и считать чистыми все ф-и, которые ему удобно считать чистыми. Я вот, честно, ни разу не видел, чтобы кто-то засунул грязную ф-ю в map. Хотя чисто теоретически это сделать можно.
Опять же, тебе никто в описании map не гарантирует последовательность вычислений, а значит если ты сунешь туда сайд=эффект - это в согласии с документацией undefined behavior, так чот никаких проблем.
> let z = ZipList
Prelude Control.Applicative> getZipList $ (+) <$> z [1,2] <*> z [3,4]
[4,6]
Prelude Control.Applicative> getZipList $ (\x y z -> x + y - z) <$> z [1,2] <*> z [3,4] <*> z [10,20]
[-6,-14]
блин дошло, что тебе надо, так бы сразу и говорил.
Да вроде так тебе и сказали с самого начала. Смысл в том, что вместо зоопарка из мапов зиплистов и прочего говна у нас один единственный мап. Модуляризация, абстракция, уменьшение количества сущностей. Сплошной профит, короче.
У тебя map, getZipList, ZipList <$>, <*>, у меня - map.
Невыводим откуда, каким алгоритмом и в какой системе типов?
в любой системе типы функция от бесконечного количества аргументов не выводим (без контекста).
т.к. если у тебя есть фунция :: a -> (a -> (a ->...a...)) и ты применил к ней n аргументов, то ты не можешь вывести, какой тип ты получишь продолжение вычисления (a -> .. -> a) или результат a. Можно рассматривать применение как комонаду, но тогда для работы тебе потребуется явное вытаскивание результата, напр. foo 1 2 3 4 & extract.
но ты конечно учитываешь, что у меня map \equiv <$> \equiv fmap и он работает для любого функтора, а не только для списков и векторов. getZipList и ZipList нужны, чтобы перейти к нестандартной аппликации списков, т.к. стандартная это применение всех функций из первого списка, к элементам второго. Чтобы нормально сравнивать ты сначала должен привести аналог обычного аппликативного функтора для списков в haskell:
я думаю, что ты не прав (в общем я тоже) тип функции от бесконечного числа аргументов, во всяком случае в haskell это a -> a -> ... -> b, скобки расставишь сам, я ленивый. В лиспе, кстати, функции от многих аргументов это функции от кортежа, возможно частичное применение функции без доп шаманств?
я бы сказал, что это проблема человека пытающегося решать стандартные проблемы нестандартными методами.
Скажи, какой тип у функции let f x = g x, если контекста у тебя нет (а значит тип g - неизвестен).
let f x = g x это не функция. В целом вопрос некорректный, переформлируй.
Оно тебе должно вернуть ошибку, т.к. ты применил ф-ю, требующую n+1 аргумент к одному аргументу
компилятор ванга? у меня фунция от произвольного кол-ва аргументов, я её очень не хотел писать, но вы же настояли, поэтому я к ней могу применть n, n+1, n*2 и прочее число аргументов и это не ошибка.
я бы сказал, что это проблема человека пытающегося решать стандартные проблемы нестандартными методами.
Это ты о чем? map вместо зипа - как раз стандартный метод.
let f x = g x это не функция.
Какой тип у функции f, которая определена как let f x = g x?
компилятор ванга?
Почему ванга?
у меня фунция от произвольного кол-ва аргументов, я её очень не хотел писать, но вы же настояли, поэтому я к ней могу применть n, n+1, n*2 и прочее число аргументов и это не ошибка.
Ах, ок, вот ты о чем. Ну да, применил n аргументов, получил результат. Например вот ф-я +, применил ее к 5 аргументам (1, 1, 1, 1, 1), получим результат - 5. Какие проблемы?
т.е. я могу лисповый мап применить, к мм.. аналогу Either, Maybe, квантовому вычислению?
Ну если напишешь map для них, то применяй сколько угодно.
а у тебя функции <*> и <$> являются функциями такого типа:
У них никакого типа нте, это же динамика.
А применять их можно только к спискам, точно так же как и в хаскеле их можно применять только к спискам. Потому что это конкретные инстансы для писков. Если хочешь чтобы можно было применять к чему-то другому - ну надо написать инстансы для чего-то другого, очевидно.
ппц.. как вы это читаете?
Как обычный текст. Это не хаскиарт, где надо в голове все парсить. Понятно, что для любителя хаскеля такая простота и читабельность очень непривычна.
Это ты о чем? map вместо зипа - как раз стандартный метод.
стандартный метод в лиспе, при этом это не стандартный метод в haskell. И я не вижу ни одной причины почему лисповый map f a b, лучше чем zipWith f a b в haskell.
Какой тип у функции f, которая определена как let f x = g x?
очевидно такой же как у функции g. Я продолжаю не понимать вопроса.
Ах, ок, вот ты о чем. Ну да, применил n аргументов, получил результат. Например вот ф-я +, применил ее к 5 аргументам (1, 1, 1, 1, 1), получим результат - 5. Какие проблемы?
да не.. всё ок... пиши так.. возможно в семантике лиспа это и добно. только не надо с этими требованиями к другим языкам лезть.
Ну если напишешь map для них, то применяй сколько угодно.
спасибо, у меня в haskell всё уже есть.
У них никакого типа нте, это же динамика.
фубар блин... я хочу понять, какие аргументы я могу передать, чтобы не было ошибки.
А применять их можно только к спискам, точно так же как и в хаскеле их можно применять только к спискам. Потому что это конкретные инстансы для писков. Если хочешь чтобы можно было применять к чему-то другому - ну надо написать инстансы для чего-то другого, очевидно.
в haskell их можно применять к _ЛЮБЫМ_ функторам.
Как обычный текст. Это не хаскиарт, где надо в голове все парсить. Понятно, что для любителя хаскеля такая простота и читабельность очень непривычна.
субьективизм так и прет.
P.S. вот и не говорите мне, что типы не нужны, меня уже задолбало после каждой пасты лиспокода пытаться понять, что она делает, какими свойствами обладает и как работает.. всё нафиг вас.
стандартный метод в лиспе, при этом это не стандартный метод в haskell.
Естественно в хаскеле он нестандартный - просто потому что хаскель так не может.
И я не вижу ни одной причины почему лисповый map f a b, лучше чем zipWith f a b в haskell.
ТАк я уже несколько раз объяснял. Одна функция лучше зоопарка. Keep it simple, не умножай сущности.
очевидно такой же как у функции g.
Какой «такой же»? назови его. Ты же сказал что можно вывести тип без контекста. Вот и выведи. Дам подсказку: тип f не может зависеть от типа g (и совпадать конечно же не может), т.к. иначе его нельзя было бы вывести без контекста (не зная g).
да не.. всё ок... пиши так.. возможно в семантике лиспа это и добно.
фубар блин... я хочу понять, какие аргументы я могу передать, чтобы не было ошибки.
В этот инстанс - списки.
в haskell их можно применять к _ЛЮБЫМ_ функторам.
Да не к любым, а только к тем, для которых у тебя инстанс аппликатива есть. Этот инстанс у тебя из воздуха не сгенерируется. haskell cannot into.
P.S. вот и не говорите мне, что типы не нужны, меня уже задолбало после каждой пасты лиспокода пытаться понять, что она делает, какими свойствами обладает и как работает..
А типы тут при чем? Из них ничего вышеописанного неясно. Например, тот же тип для <*> - скажи какими свойствами обладает <*>, как работает и т.п.? Не скажешь. Пока не посмотришь на реализацию конкретного инстанса.
Естественно в хаскеле он нестандартный - просто потому что хаскель так не может.
ну показывал, же что может.. причем способами, которые удобно объединяются и везде понятно как работают. Просто оно не недо и не удобно. В лиспе может и удобно, у меня нету опыта, чтобы судить.
ТАк я уже несколько раз объяснял. Одна функция лучше зоопарка. Keep it simple, не умножай сущности.
т.е. писать кучу map для каждого типа это хорошо, а один fmap это плохо, окай.
т.е. писать кучу map для каждого типа это хорошо, а один fmap это плохо, окай.
Как раз один fmap - это хорошо, но хаскель в такое не может, это тебе не Clean который сам инстансы генерит. В хаскеле изволь для каждого типа ручками написать свой инстанс функтора.
мне кажетя я уже писал про субъективизм да?
Так я же оперирую объективными критериями. Простота, меньшее количество сущностей.
Да не к любым, а только к тем, для которых у тебя инстанс аппликатива есть. Этот инстанс у тебя из воздуха не сгенерируется. haskell cannot into
да, в этом месте уговорил, это правда абсолютно ничего не меняет.
А типы тут при чем? Из них ничего вышеописанного неясно. Например, тот же тип для <*> - скажи какими свойствами обладает <*>, как работает и т.п.? Не скажешь. Пока не посмотришь на реализацию конкретного инстанса.
типы сильно облегчают понимание. инстанс обладает всеми св-вами, требуемыми applicative, реализацию да не скажу, но зачастую это или ясно из типа, или не важно.
Как раз один fmap - это хорошо, но хаскель в такое не может, это тебе не Clean который сам инстансы генерит. В хаскеле изволь для каждого типа ручками написать свой инстанс функтора.
{-# LANGUAGE DeriveFunctor #-}
data MyType a = A a deriving (Eq, Show, Functor)
Prelude> :e
[1 of 1] Compiling Main ( 12.hs, interpreted )
Ok, modules loaded: Main.
*Main> :e
Ok, modules loaded: Main.
да, в этом месте уговорил, это правда абсолютно ничего не меняет.
Что значит не меняет?
И вообще ты зачем-то смешиваешь два совершенно разных концепта: ad-hoc полиморфизм (тайпклассы хаскеля) и variable-arity полиморфизм (ф-и с разным коилчеством аргументов в лиспе). Эти концепты независимы и они могут быть реализованы в ЯП вместе безо всяких проблем, этому ничто не мешает. Не надо их противопоставлять, это неверно.
типы сильно облегчают понимание. инстанс обладает всеми св-вами, требуемыми applicative
Это тебе никто не гарантирует.
но зачастую это или ясно из типа, или не важно.
Как раз реализация-то и важна. Точнее не реализация, а семантика конкретного инстанса. Видишь ли, вот есть у тебя ф-я, ты ее применяешь. Это значит, что ты знаешь как она работает. Это значит что типы тебе уже не нужны (т.к. ты обладаешь более полной информацией). С другой стороны, если ты не знаешь как ф-я работает, то типы тебе уже не помогут, т.к. ты эту ф-ю применять не можешь.
И это мы говорим о окнкретной ф-и (то есть не ad-hoc полиморфной) в случае ad-hoc поилморфной ф-и вообще все тухло, надо знать именно инстанс. Если ты знаешь, что T - функтор, или монада или еще что - это тебе не дает никакой абсолютно полезной информации, пока ты не узнаешь какой это конкретно функтор и как работают соответствующие инстансы.
Ну сделали специальный костыль в конкретном компиляторе специально для некоторых тайпклассов, это совсем не заслуга языка. Речь то о том чтобы можно было самому делать генерализованные ф-и.
Вообще кстати смешно как хаскелисты лепят на каждый чих расширения языка, перепердоливая попутно компилятор, а потом кукарекают на тему «если у вас макросы это слабость языка блаблабла», хотя сами же и демонстрируют на сколько в реальности для языка полезны макросы.
И вообще ты зачем-то смешиваешь два совершенно разных концепта: ad-hoc полиморфизм (тайпклассы хаскеля) и variable-arity полиморфизм (ф-и с разным коилчеством аргументов в лиспе).
наверное я их смешиваю потому, что variable-arity полиморфизм в haskell реализуется через классы типов, я честно не хотел его писать, но раз потребовали...
Это тебе никто не гарантирует.
ну можно конечно реализовать направильный аппликативный функтор..
Если ты знаешь, что T - функтор, или монада или еще что - это тебе не дает никакой абсолютно полезной информации, пока ты не узнаешь какой это конкретно функтор и как работают соответствующие инстансы.