Есть следующий алгебраический тип данных:data D = D1 Char | D2 CharИ для него не определен инстанс класса Eq. Т.е. мы не можем в отношений значений этого типа данных использовать такие понятия как "равны", "не равны", "одни и те же" и т.п.Haskell это, якобы, чистый язык. Чтобы язык был чистым, в нем все функций должны быть детерминированным. Т.е функция должна возвращать всегда одно и то же значение, если ей передают один и тот же аргумент.Является ли следующая функция чистой:foo :: Char -> Dfoo 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 я вообще молчу.
>Prelude> foo 'a' == foo 'b'>FalseТ.е.Prelude> foo 'a' == foo 'a'Falseseflfix
репортнул как шитпостинг
Зачем так сложно?data D = Dinstance Eq D where (==) x y = Falsemain = print $ D == DТолько определение у чистой функции совсем другое, оно не требует == у результата.
>>677748>Только определение у чистой функции совсем другое, оно не требует == у результата. И ты его, конечно же, не дашь.
>>677702 (OP)>И для него не определен инстанс класса Eq.Если какой-то тип не принадлежит к какому-то тайпклассу, это не значит что какая-то функция не может возвращать одно и то же значение этого типа. Это всего лишь значит что программист не определил инстанс этого тайпкласса для этого типа.>Дальше, монада IO.http://stackoverflow.com/questions/4063778/in-what-sense-is-the-io-monad-pureмимоскалаёб
>>677859>Если какой-то тип не принадлежит к какому-то тайпклассу, это не значит что какая-то функция не может возвращать одно и то же значение этого типа. Что такое "одно и то же значение этого типа" если этот тип не принадлежит тайпклассу Eq?
>>677702 (OP)>функция должна возвращать всегда одно и то же значение, если ей передают один и тот же аргументПокажи что это не так без хаков с определением некорректных eq/неопределением eq.
>>677914Это значит что можно аналитически показать что значения типа равны. Собственно в чистом языке код и будет этим доказательством (без unsafe-хуйни очевидно).>>677943Слабый аргумент, для типов-функций вообще невозможно написать Eq, это алгоритмически неразрешимая задача. Но можно показать что например f(x) = x + 2 - та же функция что и g(x) = x + 1 + 1.
>>677859Я, наверное, что-то не понимаю, но так же можно сказать, что и сишка тоже пюре. Просто каждая функция принимает мир implicitly.
>>677762В чистом языке любую функцию можно заменить ее результатом и программа не изменится. То естьdata D = Dinstance Eq D where (==) x y = Falseyoba :: Int -> Dyoba x = Dmain = print $ (yoba 5) == (yoba 5)подставляем yoba 5:data D = Dinstance Eq D where (==) x y = Falsemain = print $ D == DПрограмма выводит одно и то же, значит yoba - чистая.
>>678203>функция принимает мир implicitly.>принимает implicitlyНет такого понятия ни в математике, ни в сишке.Ну и IO не едиственный источник нечистоты, есть еще неконтролируемое состояние. Почитай про referential transparency.
>>678211import System.Randomyoba :: Int -> IO ayoba x = randomIOmain = yoba 5 >>= printподставляем yoba 5:import System.Randommain = randomIO >>= printПрограмма выводит одно и то... wait, OH SHI-- значит yoba - не чистая.
>>678257>yoba :: Int -> IO ayoba :: Random a => Int -> IO aselffix
>>678031define "аналитически показать что значения типа равны"
>>678269https://ru.wikipedia.org/wiki/Математическое_доказательство>>678257Хуй знает с чего тот челик взял что ВЫВОД main относится к чистоте.
>>678257Ты не понимаешь, что такое IO. IO Int - это функция world -> (Int, world). И yoba как возвращала world -> (Int, world) так и возвращает.
> EqУ тебя неправильное равенство же. Вот правильное:data (=) : a -> b -> Type where Refl : x = xВозьми https://hackage.haskell.org/package/base-4.8.2.0/docs/Data-Type-Equality.html и попробуй снова.
>>678308>https://ru.wikipedia.org/wiki/Математическое_доказательствоИ как ты будешь доказывать, что значения типа равны, если не определено что такое "значения типа равны", т.е. не задано отношение равенства? Это все равно что доказывать, что два числа являются близнецами, не говоря при этом что значит "два числа являются близнецами".
>>678383При чем тут равенство типов?
>>678394Ну например есть функция Int => SingletonType, где SingletonType имеет только одно значение, но SingletonType не принадлежит тайпклассу Eq.Но это чисто умозрительный пример, в чистом языке программист всегда знает что значит равенство значений конкретного типа, потому что знает что значит равенство всех примитивов, то есть написать не чистую фукнцию не выйдет вообще: тело функции и будет доказательством её чистоты.
>>678313>IO Int - это функция world -> (Int, world).Это говорят, когда нубам объясняют про мандады, на самом деле, это не совсем так. Но, в принципе, похуй, допустим, что это так.Как ты докажешь, что (yoba 5) всегда возвращает одно и то же значение типа world -> (Int, world), если отношение равенства, т.е. понятие "одно и то же", для этого типа не определено?
>>678595>yoba x = randomIOyoba это функция-константа. Как она может разные значения возвращать?
>>678692Например, если randomIO в разных местах программы дает разные значения, т.е. (randomIO :: IO Int) /= (randomIO :: IO Int).
>>678595>мандадыА ты остроумный аутист.>Но, в принципе, похуй, допустим, что это так.Внутренности IO можешь наблюдать здесь:https://hackage.haskell.org/package/base-4.8.2.0/docs/src/GHC.Base.html#line-1082Вот например как происходит заворачивание в IO:returnIO :: a -> IO areturnIO x = IO $ \ s -> (# s, x #)
>Как ты докажешь, что (yoba 5) всегда возвращает одно и то же значение типа world -> (Int, world), если отношение равенства, т.е. понятие "одно и то же", для этого типа не определено?Мне не нужно это доказывать. Мне достаточно доказать, что программы "yoba 5" и "вычисленный результат yoba 5" эквивалентны.
>>678771Ясно, ты не понял что тебе написал >>678313 и мою ссылку на stackoverflow. randomIO ничего тебе не "даёт", это значение, а не функция.
>>678771это unsafePerformIO (randomIO :: IO Int) /= unsafePerformIO (randomIO :: IO Int)Сама по себе штука IO Int - это действие которое ничего не делает, пока его не выполнит (подумай над http://ideone.com/ORZlDb). main - единственное грязное место в программе. Конечно, ты можешь заюзать unsafePerformIO, но компилятор в таком случае тебе не гарантирует ничего, так как он будет считать, что функция чистая и применять соответствующие оптимизации.
>>678816>IO Int - это действие Докажи, что два раза встречающиеся в программе randomIO это одно и то же действие.
>>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.
>>678842Золотце, ты? Может тебе еще доказать что 4 = 4?
>>678886Это еврейская математика, с бесконечностями всякими, а в арийской совсем необязательно.
>>678436Это не равенство типов, это тип-равенство.
>>677702 (OP)Пиздец, у Золотца появились последователи что ли?
>>677702 (OP)Где в оп посте пример функции, которая возвращает разные значения, при передаче ей одного аргумента
>>679960foo :: Char -> Dfoo x = D1 x
>>679967Но ведь для любого своего аргумента foo возвращает D1 от этого аргумента. Значит, foo детерминированная, поскольку D1 x -это D1 x для каждого x
>>679967А проверка на равенство - это всего лишь заданная тобой пользовательская процедура, которая никакого отношения к определению детерминированности функции не имеет, и называться она могла как угодно, равно как и возвращать какой угодно результ, какой ты ей там описал
>>679984>поскольку D1 x -это D1 x для каждого xD1 x /= D1 xПо определению.
>>678858Ты прав, что реализовано оно может быть как угодно, но таким ньюфагам, как ты, которые не понимают, что IO Int - это НЕ Int, а обещание предоставить Int когда-нибудь потом, только вот так вот на пальцах и можно объяснять.
>>679986>которая никакого отношения к определению детерминированности функции не имеетОбоснуй.
>>680029>которые не понимают, что IO Int - это НЕ IntЯ не говорил, что это IO Int это Int.>а обещание предоставить Int когда-нибудь потомIO Int это impure computation.
>>680042>Я не говорил, что это IO Int это Int.Вот тут ты одно подменяешь другим >>678257>IO Int это impure computation.Вопрос тебе на засыпку: является ли функция yoba чистой?yoba = function() { return function(){return Math.random(); } };
>>680045>Вопрос тебе на засыпку: является ли функция yoba чистой?>yoba = function() { return function(){return Math.random(); } }; Нет.yoba() === yoba() //falseMath.random = function () {return"shit"}yoba()() //"shit"Вот чистая yoba:yoba = function() { return "function(){return Math.random()"; };
>>680045>Вот тут ты одно подменяешь другим >>678257Это >>678211 подменяет.
>>680048Ответ неправильный. Функция yoba - чистая.
>>680041По определению '/=' которое ввёл ОП-полуёбок, и которое реализуется в рамках хаскельной системы, а не участвует в её реализации
>>680052Обоснуй.
>>680242define обоснуй
>>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.То есть чистота функции есть синоним ссылочной прозрачности. Если ты придумал свое определение, то это твои половые проблемы.
Бамп
>>677702 (OP)Очевидно, что чистота имеет отношение к > одно и то же значениеИ если ты определяешь "одно и то же" каким-то образом, то чистые функции могут и не существовать.
Чистый - сайд-эффекты выделены каким-то особым образомНечистый - в одну кучу, и чистота, и сайд-эффектыДжаваскрипт и Скала - и ООП, и функциональные.
>>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.Ну так рандом под него и не попадает. Он каждый раз возвращает разные значения, плюс зависит от контекста (если рассматривать типичный генератор псевдослучайных чисел - он обычно содержит в себе некое глобальное состояние, текущий элемент последовательноти).мимохуй заинтересовавшийся дискусией
>>712626var a = function() { return function() { return Math.random();} };Является ли a чистой функцией?
>>713508Да, это чистая функция возвращающая грязную (можно всюду заменить `a()` на `function() { ... }`, но нельзя заменить `Math.random()` числом).
>>713863Ну вот randomIO :: IO a это почти тоже самое, не a, а обещание вернуть a когда main склеит все действия и выполнит. Поэтому это чистая функция.