SV>>hello1 -- функция с нулём аргументов. Или нет? Она ведь ни к чему не применяется. SV>>f в моём примере -- аналог функции hello1.
К>Нет. В твоём примере f — это static int hello2 = hello1(); К>Точнее, с учётом ленивости, там будет что-то наподобие К>
А если это определение локально (в where)? Ты сейчас пол рантайма HUGS напишешь?
Хаскель -- это не си и не с++. Полного соответствия нет.
Я влез в дискуссию в ответ на конкретный вопрос: можно ли назвать функцией то, что не принимает аргументов. В С/С++ -- можно. А почему нельзя в Haskell?
SV>>Function binding семантически эквивалентно pattern binding. Вот и всё. SV>>Т.е. следующие определения абсолютно идентичны SV>>
SV>>f2 a = a + 1 -- function binding
SV>>f2 = \a -> a + 1 -- pattern binding
SV>>f2 = (+1) -- pattern binding
SV>>
SV>>В первом случае f2 биндится на function value, а в двух других -- просто на value. В чём разница между value и function value? Хз, в определении языка никакой разницы я не нашёл (вполне допускаю, впрочем, что плохо искал ).
К>Разница в том, что по умолчанию значения мономорфны, а функции полиморфны К>А в остальном — это сахар
Разница зарыта где-то в реализации. А число "7" дано мне в ощущениях Хз как оно там реализованно. Может, это функция какая-то.
SV>>Haskell Report не даёт определения понятию "функция", да и использует его непоследовательно. Поэтому вопрос, является ли "7" функцией или нет не имеет ответа. Это лишь вопрос предпочтений.
К>Ну, если термин используется абы как, то предпочтительно было бы не вносить дополнительную сумятицу и не использовать его там, где в обычной жизни его бы не стали использовать.
Не абы как, а непоследовательно. Читай, не ясно, какое мнение о сабже было у автора.
SV>>Можно пойти дальше и сказать, что в хаскеле всё является значением. И это тоже будет правдой.
К>Ну не всё, конечно. Классы и типы не являются первоклассными объектами. Но то, что является первоклассными — суть значения, по определению
SV>>И я так и не понял, в чем, собственно, причина столь большого резонанса по повожу сабжа? Что в этом утверждении плохого и неправильного?
К>Дык, попытка сделать нечто неестественное. То, что не ложится ни в математическую семантику, ни в программистскую. К>Вызывает естественный протест, во-первых, и всякие изыски, во-вторых.
Но у меня же не вызывает протест (И что за изыски, кстати?)
Ну не поворачивается у меня язык функцию main назвать значением (даже с учетом того, что функция тоже есть значение ).
Хотя у авторов Haskell Report поворачивается
HR>>A Haskell program is a collection of modules, one of which, by convention, must be called Main and must export the value main.
Хотя в другом месте аналогичные сущиности называются функциями HR>>Input Functions These functions read input from the standard input device (normally the user’s terminal). HR>> getChar :: IO Char HR>> getLine :: IO String HR>> getContents :: IO String HR>> interact :: (String -> String) -> IO () HR>> readIO :: Read a => String -> IO a HR>> readLn :: Read a => IO a
Здравствуйте, BulatZiganshin, Вы писали:
BZ>правильно: BZ>котоморфизм :: кот -> еда -> кот BZ>имей в виду что кот на входе и кот на выходе различны — второй заметно толще
Так не годится, нужен uniqueness typing хотя бы. Иначе каждый раз число котов будет удваиваться. А он один мутабельный на самом деле.
Здравствуйте, D. Mon, Вы писали:
BZ>>котоморфизм :: кот -> еда -> кот
DM>Так не годится, нужен uniqueness typing хотя бы. Иначе каждый раз число котов будет удваиваться. А он один мутабельный на самом деле.
Здравствуйте, deniok, Вы писали:
DM>> А он один мутабельный на самом деле.
D>Что такое "на самом деле"? Фиксация конкретной операционной семантики ограничивает число способов рассуждать о коте.
На самом деле = консистентная модель, валидируемая экспериментом.
Если я применю котоморфизм Булата, то получу нового кота рядом со старым. А на практике этого не происходит, вместо этого один кот меняет свои свойства (размер). Он вообще работает в ОО парадигме: ему можно послать сообщение, а он может на него среагировать (изменить координаты), а может не среагировать. Т.е. обладает состоянием к тому же.
Здравствуйте, D. Mon, Вы писали:
DM>Здравствуйте, deniok, Вы писали:
DM>>> А он один мутабельный на самом деле.
D>>Что такое "на самом деле"? Фиксация конкретной операционной семантики ограничивает число способов рассуждать о коте.
DM>На самом деле = консистентная модель, валидируемая экспериментом. DM>Если я применю котоморфизм Булата, то получу нового кота рядом со старым.
Это зависит от реализации. Оптимизатор может использовать того же самого кота, выставив в санке еды указатель на желудок этого кота.
Здравствуйте, D. Mon, Вы писали:
DM>На самом деле = консистентная модель, валидируемая экспериментом. DM>Если я применю котоморфизм Булата, то получу нового кота рядом со старым.
да. только это рядом будет не в пространстве а во времени.
Здравствуйте, BulatZiganshin, Вы писали:
BZ>>>котоморфизм :: кот -> еда -> кот
DM>>Так не годится, нужен uniqueness typing хотя бы. Иначе каждый раз число котов будет удваиваться. А он один мутабельный на самом деле.
BZ>ты ещё не постиг дао чистоты
Кот там иммутабельный и чистый. Просто он использует замыкание языка — лижет себе всё, до чего дотягивается.
SV>Я влез в дискуссию в ответ на конкретный вопрос: можно ли назвать функцией то, что не принимает аргументов. В С/С++ -- можно. А почему нельзя в Haskell?
Тут проблема не в том, что она принимает, а что она возвращает.
Если все есть функция, а 3 — константная функция, то что возвращает эта константная функция? Функция — есть однозначное отображение элементов множества A во множество B. Область определения для константной функции пуста, но что представляет собой множество значений?
Говорить, что она возвращает сама себя — бессмысленно, так как это бесконечное рекурсивное определение, тавтология неопределенного понятия.
Здравствуйте, SpaceConscience, Вы писали:
SC>>Область определения для константной функции пуста, но что представляет собой множество значений?
Если область определения пуста, то область значений тоже пуста. Вроде это очевидно.
Функция по определению что-то куда-то отображает. Числа ничего не отображают, но несут в себе значение.
Заметим, что и числа и функции можно представить в виде функций, путем добавления фиктивного параметра
1 -> f(x) = 1 + 0*x; (1)
s(x) -> g(x, y) = s(x) + 0*y;
но функция f отображает числа в числа
если же делать автоматически преобразование (1), чтобы числа называть функциями (и от понятия числа отказаться), то неясно будет какова область определения функции, так как уйдем в бесконечную рекурсию
иногда, числа неявно преобразуют в функции, когда их пытаются дифференцировать:
1'_z = 0 (здесь 1 была преобразована в функцию одного переменного z), однако от понятия числа не смогли бы отказаться, т.к. определение производной опирается на числа =)
зы: короче, я не разделяю попытку отказаться от чисел в пользу функций
Здравствуйте, uzhas, Вы писали:
SC>>>Область определения для константной функции пуста, но что представляет собой множество значений?
Для константной функции — область определения не пуста, а универсальна. Отображаем что угодно в точку.
alwaysThree = const 3
three = alwaysThree undefined-- на входе _|_ как типичный представитель универсума, на выходе - всё равно 3
main = putStrLn $ show three
U>Заметим, что и числа и функции можно представить в виде функций, путем добавления фиктивного параметра
В ФП более популярно представление чисел как комбинаторов — показателей степени повторения функции-аргумента (числа Чёрча)
0(f,x) = x
1(f,x) = f(x)
2(f,x) = f(f(x))
etc.
Поскольку комбинаторный базис SKI содержит тернарный комбинатор S, мы можем договориться, что и все остальные сущности — тоже тернарные (лишние аргументы можно забивать мусорными значениями).
Т.е.
0(f,x,_) = x
1(f,x,_) = f(x,_,_)
2(f,x,_) = f(f(x,_,_),_,_)
А чтобы передавать более трёх аргументов — надо реализовать списки на комбинаторах, и передать список.
U>зы: короче, я не разделяю попытку отказаться от чисел в пользу функций
Здравствуйте, Кодт, Вы писали:
К>В ФП более популярно представление чисел как комбинаторов — показателей степени повторения функции-аргумента (числа Чёрча)
спасибо, погуглил (но там не нашел) и пояндексил
набрел на http://msimuni.wikidot.com/fp-hw11
помогите улучшить\упростить (а может, исправить) решения на задачки 6, 7, 8:
cToInt a = a (+1) 0
cInc c = (\f -> f . (c f))
snd3 (_, b, _) = b
cDec c = (\f -> snd3 $ (c g) (f, id, False))
where g (f, x, True) = (f, f . x, True)
g (f, x, False) = (f, x, True)
К>Поскольку комбинаторный базис SKI содержит тернарный комбинатор S
где можно почитать про SKI и S ?
Здравствуйте, uzhas, Вы писали:
К>>В ФП более популярно представление чисел как комбинаторов — показателей степени повторения функции-аргумента (числа Чёрча) U>спасибо, погуглил (но там не нашел) и пояндексил
Правильно. Но, с учётом того, что f^n · f^m = f^(n+m) = f^m · f^n, можно написать и наоборот
cInc c = \f -> (c f) . f
U>snd3 (_, b, _) = b
U>cDec c = (\f -> snd3 $ (c g) (f, id, False))
U> where g (f, x, True) = (f, f . x, True)
U> g (f, x, False) = (f, x, True)
U>
В принципе, верно. Но я бы сделал попроще:
cDec c = \f x -> finish $ c (step f) (start x) where
start x = (error"вычитание из нуля!!!", x)
step f (decx, x) = (x, f x)
finish (decx, x) = decx
Этюд: придумать числа Чёрча с поддержкой отрицательных значений
К>>Поскольку комбинаторный базис SKI содержит тернарный комбинатор S U>где можно почитать про SKI и S ?
U>>snd3 (_, b, _) = b
U>>cDec c = (\f -> snd3 $ (c g) (f, id, False))
U>> where g (f, x, True) = (f, f . x, True)
U>> g (f, x, False) = (f, x, True)
U>>
К>В принципе, верно. Но я бы сделал попроще: К>
К>cDec c = \f x -> finish $ c (step f) (start x) where
К> start x = (error"вычитание из нуля!!!", x)
К> step f (decx, x) = (x, f x)
К> finish (decx, x) = decx
К>
Надо заметить, что здесь мы неявно пользуемся двумя встроенными функциями: конструктором и парсером кортежа.
Это не совсем честно, в чистом лямбда-исчисление нет иных структур, кроме функций.
Поэтому немножко рукодельничаем ещё:
-- нам нужно:
pair x y = \selector -> .....
fst xy = xy fst' where fst' = .....
snd xy = xy snd' where snd' = .....
-- чёрчева логика
CBool :: {-then-} a -> {-else-} a -> {-result-} a
true_ t e = t
false_ t e = e
if_ c t e = c t e
and_ a b = a b false_
or_ a b = a true_ b
not_ a = a false_ true_
-- и т.д.
-- реализуем
pair x y = \selector -> selector x y
fst xy = xy true_
snd xy = xy false_
-- подставляем
cDec c f x = finish $ c step f $ start where
start = pair (error"-1") x
step xy = pair (snd xy) (f $ snd xy)
finish xy = fst xy
Здравствуйте, SpaceConscience, Вы писали:
SV>>Я влез в дискуссию в ответ на конкретный вопрос: можно ли назвать функцией то, что не принимает аргументов. В С/С++ -- можно. А почему нельзя в Haskell?
SC>Тут проблема не в том, что она принимает, а что она возвращает.
SC>Если все есть функция, а 3 — константная функция, то что возвращает эта константная функция? Функция — есть однозначное отображение элементов множества A во множество B. Область определения для константной функции пуста, но что представляет собой множество значений?
SC>Говорить, что она возвращает сама себя — бессмысленно, так как это бесконечное рекурсивное определение, тавтология неопределенного понятия.
Число 3 не является функцией в математике. С этим никто не спорит. Она ничего не возвращает, поскольку ни к чему не применяется.
Но в субже нет слова "математика". Зато есть слово "хаскел". А определение языка хаскел явно называет сущности, подобные числу 3, функциями. Т.е. число 3 является функцией в языке хаскел. Точка.
Здравствуйте, SolVolkov, Вы писали:
SV> А определение языка хаскел явно называет сущности, подобные числу 3, функциями. Т.е. число 3 является функцией в языке хаскел. Точка.
Здравствуйте, D. Mon, Вы писали:
DM>Здравствуйте, SolVolkov, Вы писали:
SV>> А определение языка хаскел явно называет сущности, подобные числу 3, функциями. Т.е. число 3 является функцией в языке хаскел. Точка.
DM>А ссылку не дашь на такую глупость?
SV>Input Functions These functions read input from the standard input device (normally the user’s terminal).
SV> getChar :: IO Char
SV> getLine :: IO String
SV> getContents :: IO String
SV> interact :: (String -> String) -> IO ()
SV> readIO :: Read a => String -> IO a
SV> readLn :: Read a => IO a
SV>
У IO t ручка вызова недоступна для посторонних, то есть, нельзя просто так написать let x = getChar ().
Только через let x = unsafePerformIO getChar, которое сделает что-то наподобие (unboxIO getChar) ().
Или в недрах оператора >>, который для монады IO сделает то же самое.
Короче говоря, тщательно забоксированная честная функция.
Любое значение можно превратить в IO-функцию
constIO :: x -> IO x
constIO x = return x
Как, впрочем, и в обычную функцию
type Call x = () -> x
constCall :: x -> Call x
constCall x = const x
Но не наоборот же! Не получится применить ($()) или unsafePerformIO к произвольному значению, — только к соответствующей функции.
Здравствуйте, Кодт, Вы писали:
К>У IO t ручка вызова недоступна для посторонних, то есть, нельзя просто так написать let x = getChar (). К>Только через let x = unsafePerformIO getChar, которое сделает что-то наподобие (unboxIO getChar) (). К>Или в недрах оператора >>, который для монады IO сделает то же самое. К>Короче говоря, тщательно забоксированная честная функция.
IO t -- абстрактный тип данных. Как он там устроен внутри -- детали реализации.
Точно так же можно сказать, что у 3 ручка вызова недоступна для посторонних. Причём, совершенно не важно, существует ли такая реализация на самом деле.
К>Любое значение можно превратить в IO-функцию К>
К>constIO :: x -> IO x
К>constIO x = return x
К>
К>Как, впрочем, и в обычную функцию К>
К>type Call x = () -> x
К>constCall :: x -> Call x
К>constCall x = const x
К>
К>Но не наоборот же! Не получится применить ($()) или unsafePerformIO к произвольному значению, — только к соответствующей функции.
Не понимаю, к чему это всё. Что лично ты понимаешь под функцией в haskell? getChar :: IO Char -- это функция или нет? Если да, то почему f :: Int -- нет?