Обновить
59

Пользователь

22
Подписчики
Отправить сообщение
Честно, не нашёлся, что ответить.
Что мешает нам использовать напрямую класс в ООП и заставляет нас описывать какой-то интерфейс?
Ничего не мешает, это просто удобная абстракция. В частном случае можно вызывать функции. Но это один частный случай.
Код забыл:
runIdentity $ do
    x <- return 5
    y <- return $ x + 4
    return $ y * 2
А функции подходят, только это частный случай, когда результат предыдущего вычисления просто передаётся следующей функции.
Подозревал об этом, когда писал, но не проверил.
Буду иметь в виду.
Да, спасибо, исправил.

Насколько я узнал, название идёт из axiom of comprehension, что по-русски обычно переводят как «аксиома выделения». Но «выделение списков» как-то не звучит.
Не понял вопроса. :( Во время вычисления coeval разве не будут производиться side-effecting операции?

Я скорее про «философическую» сторону вопроса.
Обычный IO воспринимается, как World -> (a, World). Т.о. хотя мы в сам World залезть не можем, реализация — может, и putChar можно написать так:
putChar c w@(World (Heap h) ... (Descriptors d)) = case lookup d stdout of
    Just f -> Success ((), World (replaceInHeap h f c) ... (Descriptors d))
    Nothing -> Exception "hmm..." ((), w)

В комонадах же сначала вызывается enableOI, который дублирует окружение, а затем mapOI, который из функции OI Handle -> Char делает OI (OI Handle) -> OI Char.
Цитата: «The operational effect of co-ext f allows a function f, which accepts arguments that may depend upon the current IO environment, to propagate the IO environment as an implicit parameter along with its result»
где co-ext f = (mapOI f).enableOI
Т.е. некий базовый putChar должен бы иметь тип OI (OI Char) -> OI () и использоваться без mapOI, но тогда неясно, как его использовать внутри своих функций.

Пока писал, подумалось, что Handle может внутри себя содержать все нужные данные (т.е. это не дескриптор, а сами данные), тогда coeval stdin возвращает некоторые данные, а также может выполнить некоторые изменения в окружении (что за изменения — скрыто в реализации OI), а getChar, зная внутреннее устройство Handle достаёт оттуда символ.
Вариант.
Соответственно main будет иметь тип coMain :: OI () -> ()
coMain env = env =>> coGetChar stdin =>> coPutChar stdout

В случае с OI будет то же самое
А как же тогда осуществлять побочные эффекты?
Вообще, почему-то в Хаскеле монады определяются через return и bind, а не через return, fmap и join
Думаю, в немалой степени из-за do-notation. Там напрямую используются >>= и >>, а так будут лишние действия. Хотя не знаю, будет ли через fmap/join медленнее.
А помоему, довольно понятно: OI Handle -> Char это функция, которая возвращает Char из файла. Это скорее «по-другому» (а так — вполне эстетично).
Я тоже об этом подумал :)
Но тогда можно подумать, что
getChars :: OI Handle -> OI Handle -> (Char, Char)
Возвращает (Char, Char) из двух файлов, а это не так.
Да и OI a обязан быть последним аргументом.
Или я что-то путаю?
Ну т.е. понятно, что getChars f1 f2 = (getChar f1, getChar f2), но как этот getChars в cobind передать?
Честно говоря, не понял я, почему за ними будущее.
У меня есть некоторые претензии/вопросы:
1. Что ни говори, а в чистом языке тип a -> b -> () не может (не должен) иметь побочных эффектов, что бы он там ни принимал
2. Скрытое возвращение результата изменения внешнего мира предлагается делать при помощи mapOI, которая примет функцию f :: OI a -> b, а вернёт f :: OI (OI a) -> OI b. Т.е. f теперь как бы принимает копию окружения и возвращает новую. Но ведь f сам ничего не возвращает, а mapIO ничего не знает об f, следовательно реализация mapOI может разве что скопировать окружение.
3. Теперь все функции с побочными эффектами должны иметь тип OI a -> b, не эстетично
4. IO a имеет вполне понятный смысл — вычисление значения типа a, чего не сказать об OI a -> b

Я даже для State с трудом представляю, как менять этот самый State из функции, а не снаружи при помощи специально написанной local, потому что duplicate всего лишь копирует (о чём я в пункте 2 написал).
Им что, лень добавить лишний проход компилятора, лучше пусть программист мучается?

Во-первых компиляция и так не летает, а во-вторых, сдаётся мне, существует пример, в котором без предварительного объявления выбрать верный путь разбора будет невозможно, хотя я его привести не возьмусь.
Спасибо, поправил
С прологом в таком примере, конечно, тягаться почти нереально :)
Так что я даже не пытаюсь, просто ещё одно решение.
import Data.List

bracket '[' = Just ']'
bracket '(' = Just ')'
bracket '{' = Just '}'
bracket _ = Nothing

brackets [] = True
brackets [x] = False
brackets (l:r:s)
    | Just r' <- bracket l
    , True <- r' == r
    = brackets s
    | Just r' <- bracket l
    , sub <- last $ filter brackets $ inits (r:s)
    , (r'':tl) <- drop (length sub) (r:s)
    , True <- r'' == r'
    = brackets tl
    | otherwise = False
Я, честно говоря, не понял Вашего вопроса
Я блог для того и начал, чтобы написать на Хаскеле программу, но для начала надо же дать хоть что-то. Я не ставлю целью рассказать всё, но если при реализации возникнут вопросы, всегда можно посмотреть предыдущую статью, где про это написано. Если всё равно непнонятно, то для более полной информации есть интернет.
Ну не знаю. У подростков период протеста, и когда они узнают, что всё, что им говорили о наркотиках, — враньё, эффект может получиться обратный.
Может и больше. У меня 4 и выводится BINGO, в каком бы порядке я не запустил потоки.
Точнее из-за их отсутствия в вышеприведённом коде
Я думаю сработает из-за memory barriers, в test_aa будут писаться нули из aa, хотя на другом процессоре туда уже записали 1.
Чистота — можно не пользоваться императивными возможностями языков, которые их предоставляеют.

Важна декларативность чистоты и нечистоты. И когда это выражается на системе типов — выглядит естественно. Хотя можно и ключевое слово ввести.

всяких классов типов

Ну я бы не говорил «всякие» :)
Помощнее интерфейсов-то будут.
Мне хватает того факта, что вероятность есть, и она выше, например, вероятности угадать 5-ти символьный пароль с первого раза

Именно, что данный факт ни о чём не говорит, поэтому и выводов никаких сделать нельзя.
Если вас интересует, есть ли вероятность, что darcs провалился из-за ЯП, то да, есть.
Если вы хотите доказать какую-то точку зрения, я бы хотел увидеть как формулировку точки зрения, так и оценку вероятности.
Иначе это выглядит как переливание из пустого в порожнее. Верным может оказаться любое мнение.

Информация

В рейтинге
Не участвует
Откуда
Россия
Дата рождения
Зарегистрирован
Активность