[Ответить в тред] Ответить в тред

03/04/16 - Набор в модераторы 03.04 по 8.04
26/03/16 - Конкурс: Помоги гомункулу обрести семью!
15/10/15 - Набор в модераторы 15.10 по 17.10



[Назад][Обновить тред][Вниз][Каталог] [ Автообновление ] 56 | 1 | 17
Назад Вниз Каталог Обновить

Чистота haskell это миф Аноним 05/03/16 Суб 21:55:09  677702  
14572041095310.png (4Кб, 120x84)
Есть следующий алгебраический тип данных:
data D = D1 Char | D2 Char
И для него не определен инстанс класса Eq. Т.е. мы не можем в отношений значений этого типа данных использовать такие понятия как "равны", "не равны", "одни и те же" и т.п.

Haskell это, якобы, чистый язык. Чтобы язык был чистым, в нем все функций должны быть детерминированным. Т.е функция должна возвращать всегда одно и то же значение, если ей передают один и тот же аргумент.

Является ли следующая функция чистой:
foo :: Char -> D
foo x = D1 x
?

А мы пока не можем даже ответить на этот вопрос:
Prelude> foo 'a' == foo 'b'
No instance for (Eq D) arising from a use of `=='
Т.е. это хуй пойми что: это и не чистая функция и не нечистая, к ней вообще понятия "(не)чистая" не применимо.

А теперь делаем следующее:
instance Eq D where (==) x y = False
И проверяем:
Prelude> foo 'a' == foo 'b'
False

Что? Наебали? Haskell, получается, ни разу не чистый язык.

Дальше, монада IO. Например, getLine имеет тип IO String. Для IO a не определен истанс тайпкласса Eq. Поэтому нельзя сказать, что getLine имеет одно и то же значение в каждом месте вашей программы. Это просто неправда потому, что для IO String отношение равенства не определено.
Про unsafePerformIO я вообще молчу.
Аноним 05/03/16 Суб 22:06:46  677714
>Prelude> foo 'a' == foo 'b'
>False
Т.е.
Prelude> foo 'a' == foo 'a'
False
seflfix
Аноним 05/03/16 Суб 22:24:36  677726
репортнул как шитпостинг
Аноним 05/03/16 Суб 22:41:47  677748
Зачем так сложно?

data D = D
instance Eq D where (==) x y = False
main = print $ D == D

Только определение у чистой функции совсем другое, оно не требует == у результата.
Аноним 05/03/16 Суб 22:58:20  677762
>>677748
>Только определение у чистой функции совсем другое, оно не требует == у результата.
И ты его, конечно же, не дашь.
Аноним 06/03/16 Вск 01:09:53  677859
>>677702 (OP)
>И для него не определен инстанс класса Eq.
Если какой-то тип не принадлежит к какому-то тайпклассу, это не значит что какая-то функция не может возвращать одно и то же значение этого типа. Это всего лишь значит что программист не определил инстанс этого тайпкласса для этого типа.
>Дальше, монада IO.
http://stackoverflow.com/questions/4063778/in-what-sense-is-the-io-monad-pure
мимоскалаёб
Аноним 06/03/16 Вск 04:07:43  677914
>>677859
>Если какой-то тип не принадлежит к какому-то тайпклассу, это не значит что какая-то функция не может возвращать одно и то же значение этого типа.
Что такое "одно и то же значение этого типа" если этот тип не принадлежит тайпклассу Eq?
Аноним 06/03/16 Вск 08:12:43  677943
>>677702 (OP)
>функция должна возвращать всегда одно и то же значение, если ей передают один и тот же аргумент

Покажи что это не так без хаков с определением некорректных eq/неопределением eq.
Аноним 06/03/16 Вск 12:34:46  678031
>>677914
Это значит что можно аналитически показать что значения типа равны. Собственно в чистом языке код и будет этим доказательством (без unsafe-хуйни очевидно).
>>677943
Слабый аргумент, для типов-функций вообще невозможно написать Eq, это алгоритмически неразрешимая задача. Но можно показать что например f(x) = x + 2 - та же функция что и g(x) = x + 1 + 1.
Аноним 06/03/16 Вск 15:03:57  678203
>>677859
Я, наверное, что-то не понимаю, но так же можно сказать, что и сишка тоже пюре. Просто каждая функция принимает мир implicitly.
Аноним 06/03/16 Вск 15:19:01  678211
>>677762
В чистом языке любую функцию можно заменить ее результатом и программа не изменится. То есть

data D = D
instance Eq D where (==) x y = False
yoba :: Int -> D
yoba x = D
main = print $ (yoba 5) == (yoba 5)

подставляем yoba 5:

data D = D
instance Eq D where (==) x y = False
main = print $ D == D

Программа выводит одно и то же, значит yoba - чистая.
Аноним 06/03/16 Вск 16:15:33  678253
>>678203
>функция принимает мир implicitly.
>принимает implicitly
Нет такого понятия ни в математике, ни в сишке.
Ну и IO не едиственный источник нечистоты, есть еще неконтролируемое состояние. Почитай про referential transparency.
Аноним 06/03/16 Вск 16:22:27  678257
>>678211
import System.Random
yoba :: Int -> IO a
yoba x = randomIO
main = yoba 5 >>= print

подставляем yoba 5:

import System.Random
main = randomIO >>= print

Программа выводит одно и то... wait, OH SHI-- значит yoba - не чистая.
Аноним 06/03/16 Вск 16:28:16  678264
>>678257
>yoba :: Int -> IO a
yoba :: Random a => Int -> IO a
selffix
Аноним 06/03/16 Вск 16:32:43  678269
>>678031
define "аналитически показать что значения типа равны"
Аноним 06/03/16 Вск 16:59:25  678308
>>678269
https://ru.wikipedia.org/wiki/Математическое_доказательство
>>678257
Хуй знает с чего тот челик взял что ВЫВОД main относится к чистоте.
Аноним 06/03/16 Вск 17:05:17  678313
>>678257
Ты не понимаешь, что такое IO. IO Int - это функция world -> (Int, world). И yoba как возвращала world -> (Int, world) так и возвращает.
Аноним 06/03/16 Вск 17:53:40  678383
> Eq
У тебя неправильное равенство же. Вот правильное:
data (=) : a -> b -> Type where
Refl : x = x

Возьми https://hackage.haskell.org/package/base-4.8.2.0/docs/Data-Type-Equality.html и попробуй снова.
Аноним 06/03/16 Вск 17:58:54  678394
>>678308
>https://ru.wikipedia.org/wiki/Математическое_доказательство
И как ты будешь доказывать, что значения типа равны, если не определено что такое "значения типа равны", т.е. не задано отношение равенства? Это все равно что доказывать, что два числа являются близнецами, не говоря при этом что значит "два числа являются близнецами".
Аноним 06/03/16 Вск 18:33:44  678436
>>678383
При чем тут равенство типов?
Аноним 06/03/16 Вск 20:19:15  678580
>>678394
Ну например есть функция Int => SingletonType, где SingletonType имеет только одно значение, но SingletonType не принадлежит тайпклассу Eq.
Но это чисто умозрительный пример, в чистом языке программист всегда знает что значит равенство значений конкретного типа, потому что знает что значит равенство всех примитивов, то есть написать не чистую фукнцию не выйдет вообще: тело функции и будет доказательством её чистоты.
Аноним 06/03/16 Вск 20:24:00  678595
>>678313
>IO Int - это функция world -> (Int, world).
Это говорят, когда нубам объясняют про мандады, на самом деле, это не совсем так. Но, в принципе, похуй, допустим, что это так.

Как ты докажешь, что (yoba 5) всегда возвращает одно и то же значение типа world -> (Int, world), если отношение равенства, т.е. понятие "одно и то же", для этого типа не определено?
Аноним 06/03/16 Вск 21:18:12  678692
>>678595
>yoba x = randomIO
yoba это функция-константа. Как она может разные значения возвращать?
Аноним 06/03/16 Вск 22:20:17  678771
>>678692
Например, если randomIO в разных местах программы дает разные значения, т.е. (randomIO :: IO Int) /= (randomIO :: IO Int).
Аноним 06/03/16 Вск 22:45:39  678794
>>678595
>мандады
А ты остроумный аутист.
>Но, в принципе, похуй, допустим, что это так.
Внутренности IO можешь наблюдать здесь:
https://hackage.haskell.org/package/base-4.8.2.0/docs/src/GHC.Base.html#line-1082
Вот например как происходит заворачивание в IO:
returnIO :: a -> IO a
returnIO x = IO $ \ s -> (# s, x #)
Аноним 06/03/16 Вск 22:48:10  678798
>Как ты докажешь, что (yoba 5) всегда возвращает одно и то же значение типа world -> (Int, world), если отношение равенства, т.е. понятие "одно и то же", для этого типа не определено?
Мне не нужно это доказывать. Мне достаточно доказать, что программы "yoba 5" и "вычисленный результат yoba 5" эквивалентны.
Аноним 06/03/16 Вск 22:55:19  678808
>>678771
Ясно, ты не понял что тебе написал >>678313 и мою ссылку на stackoverflow. randomIO ничего тебе не "даёт", это значение, а не функция.
Аноним 06/03/16 Вск 23:01:24  678816
>>678771
это unsafePerformIO (randomIO :: IO Int) /= unsafePerformIO (randomIO :: IO Int)
Сама по себе штука IO Int - это действие которое ничего не делает, пока его не выполнит (подумай над http://ideone.com/ORZlDb). main - единственное грязное место в программе. Конечно, ты можешь заюзать unsafePerformIO, но компилятор в таком случае тебе не гарантирует ничего, так как он будет считать, что функция чистая и применять соответствующие оптимизации.
Аноним 06/03/16 Вск 23:31:20  678842
>>678816
>IO Int - это действие
Докажи, что два раза встречающиеся в программе randomIO это одно и то же действие.
Аноним 06/03/16 Вск 23:53:37  678858
>>678794
>А ты остроумный аутист.
Ньюфак штоле?
>Внутренности IO можешь наблюдать здесь:
>https://hackage.haskell.org/package/base-4.8.2.0/docs/src/GHC.Base.html#line-1082
Это детали имплементации IO в ghc. Haskell /= ghc. Т.е. оно не обязательно так должно быть реализовано.
http://stackoverflow.com/questions/9244538/what-are-the-definitions-for-and-return-for-the-io-monad
>There is no specific implementation for IO; it's an abstract type, with the exact implementation left undefined by the Haskell Report. Indeed, there's nothing stopping an implementation implementing IO and its Monad instance as compiler primitives, with no Haskell implementation at all.

>Basically, Monad is used as an interface to IO, which cannot itself be implemented in pure Haskell. That's probably all you need to know at this stage, and diving into implementation details is likely to just confuse, rather than give insight.

>That said, if you look at GHC's source code, you'll find that it represents IO a as a function looking like State# RealWorld -> (# State# RealWorld, a #) (using an unboxed tuple as the return type), but this is misleading; it's an implementation detail, and these State# RealWorld values do not actually exist at runtime. IO is not a state monad, in theory or in practice.

>Instead, GHC uses impure primitives to implement these IO operations; the State# RealWorld "values" are only to stop the compiler reordering statements by introducing data dependencies from one statement to the next.
Аноним 07/03/16 Пнд 00:16:47  678886
>>678842
Золотце, ты? Может тебе еще доказать что 4 = 4?
Аноним 07/03/16 Пнд 05:16:56  679096
>>678886
Это еврейская математика, с бесконечностями всякими, а в арийской совсем необязательно.
Аноним 07/03/16 Пнд 09:54:39  679154
>>678436
Это не равенство типов, это тип-равенство.
Аноним 07/03/16 Пнд 12:29:12  679224
>>677702 (OP)
Пиздец, у Золотца появились последователи что ли?
Аноним 08/03/16 Втр 00:40:10  679960
>>677702 (OP)
Где в оп посте пример функции, которая возвращает разные значения, при передаче ей одного аргумента
Аноним 08/03/16 Втр 00:48:33  679967
>>679960
foo :: Char -> D
foo x = D1 x
Аноним 08/03/16 Втр 01:32:07  679984
>>679967
Но ведь для любого своего аргумента foo возвращает D1 от этого аргумента. Значит, foo детерминированная, поскольку D1 x -это D1 x для каждого x
Аноним 08/03/16 Втр 01:33:46  679986
>>679967
А проверка на равенство - это всего лишь заданная тобой пользовательская процедура, которая никакого отношения к определению детерминированности функции не имеет, и называться она могла как угодно, равно как и возвращать какой угодно результ, какой ты ей там описал
Аноним 08/03/16 Втр 03:37:15  680025
>>679984
>поскольку D1 x -это D1 x для каждого x
D1 x /= D1 x
По определению.
Аноним 08/03/16 Втр 03:55:54  680029
>>678858
Ты прав, что реализовано оно может быть как угодно, но таким ньюфагам, как ты, которые не понимают, что IO Int - это НЕ Int, а обещание предоставить Int когда-нибудь потом, только вот так вот на пальцах и можно объяснять.
Аноним 08/03/16 Втр 05:15:55  680041
>>679986
>которая никакого отношения к определению детерминированности функции не имеет
Обоснуй.
Аноним 08/03/16 Втр 05:20:23  680042
>>680029
>которые не понимают, что IO Int - это НЕ Int
Я не говорил, что это IO Int это Int.
>а обещание предоставить Int когда-нибудь потом
IO Int это impure computation.
Аноним 08/03/16 Втр 05:41:10  680045
>>680042
>Я не говорил, что это IO Int это Int.
Вот тут ты одно подменяешь другим >>678257
>IO Int это impure computation.
Вопрос тебе на засыпку: является ли функция yoba чистой?

yoba = function() { return function(){return Math.random(); } };
Аноним 08/03/16 Втр 06:14:35  680048
>>680045
>Вопрос тебе на засыпку: является ли функция yoba чистой?
>yoba = function() { return function(){return Math.random(); } };
Нет.
yoba() === yoba() //false
Math.random = function () {return"shit"}
yoba()() //"shit"

Вот чистая yoba:
yoba = function() { return "function(){return Math.random()"; };
Аноним 08/03/16 Втр 06:19:57  680049
>>680045
>Вот тут ты одно подменяешь другим >>678257
Это >>678211 подменяет.
Аноним 08/03/16 Втр 06:53:37  680052
>>680048
Ответ неправильный. Функция yoba - чистая.
Аноним 08/03/16 Втр 12:35:58  680181
>>680041
По определению '/=' которое ввёл ОП-полуёбок, и которое реализуется в рамках хаскельной системы, а не участвует в её реализации
Аноним 08/03/16 Втр 13:59:51  680242
>>680052
Обоснуй.
Аноним 08/03/16 Втр 18:51:08  680668
>>680242
define обоснуй
Аноним 08/03/16 Втр 20:17:07  680800
>>680242
Поищи определение pure function, не на википедии (где даже ссылок нет), а в научных статьях. Согласно http://cs.stackexchange.com/questions/24406/is-there-a-canonical-definition-of-pure-function оно введено в Integrating functional and imperative programming (1986) by Gifford and Lucassen, где говорится:

a PURE is referentially transparent: it does not cause side-effects, its value is not affected by side-effects, and it returns the same value each time it is evaluated.

То есть чистота функции есть синоним ссылочной прозрачности. Если ты придумал свое определение, то это твои половые проблемы.
Аноним 14/03/16 Пнд 14:18:03  687444
Бамп
Аноним 14/03/16 Пнд 14:19:46  687447
>>677702 (OP)
Очевидно, что чистота имеет отношение к
> одно и то же значение
И если ты определяешь "одно и то же" каким-то образом, то чистые функции могут и не существовать.
Аноним 22/03/16 Втр 03:45:47  694874
Чистый - сайд-эффекты выделены каким-то особым образом
Нечистый - в одну кучу, и чистота, и сайд-эффекты
Джаваскрипт и Скала - и ООП, и функциональные.
Аноним 10/04/16 Вск 12:38:53  712626
>>680800
>it does not cause side-effects, its value is not affected by side-effects, and it returns the same value each time it is evaluated.
Ну так рандом под него и не попадает. Он каждый раз возвращает разные значения, плюс зависит от контекста (если рассматривать типичный генератор псевдослучайных чисел - он обычно содержит в себе некое глобальное состояние, текущий элемент последовательноти).

мимохуй заинтересовавшийся дискусией
Аноним 11/04/16 Пнд 02:39:56  713508
>>712626
var a = function() { return function() { return Math.random();} };
Является ли a чистой функцией?
Аноним 11/04/16 Пнд 16:40:31  713863
>>713508
Да, это чистая функция возвращающая грязную (можно всюду заменить `a()` на `function() { ... }`, но нельзя заменить `Math.random()` числом).
Аноним 11/04/16 Пнд 18:12:59  713936
>>713863
Ну вот randomIO :: IO a это почти тоже самое, не a, а обещание вернуть a когда main склеит все действия и выполнит. Поэтому это чистая функция.

[Назад][Обновить тред][Вверх][Каталог] [Реквест разбана] [Подписаться на тред] [ ] 56 | 1 | 17
Назад Вверх Каталог Обновить

Топ тредов