A>>>Ага, но разбираться все таки проще с длинными именами было. T>>Возьми, да перепиши по своему. Это поспособствует пониманию. Я вполне серььёзно говорю, ведь тебе придётся выразить краткую запись во многих словах, таким образом, понять смысл и выразить по своему.
A>Переписал уже, причем только одна переменная с длинным именем получилась.
A>Я ожидал что есть какой то гайд, где расписаны рекомендации и мотивации к именованию переменных.
D>>instance Monad (State s) where
D>> return a = State $ \s -> (a, s)
D>> m >>= k = State $ \s -> let
D>> (a, s') = runState m s
D>> in runState (k a) s'
D>>
A>Непонятно, почему здесь используется k, а не f, например?
Опасные вопросы задаёшь
Потому, что это k не произвольная функция, а штука с типом k :: a -> m b; каждому пижону известно, что это называется стрелка Клейсли:
newtype Kleisli m a b = Kleisli {
runKleisli :: a -> m b
}
Здравствуйте, achmed, Вы писали:
A>Видимо это привычка после мейнстримовых языков: где у каждого параметра есть имя, которое является самодокументируемым. A>Хотя не совсем понятно какие были бы имена для callCC.
Наверное, тут и "порылась собака": хаскель способствует повышению абстракции до "жёстких" вещей из ТК, где уже сам тип функции является довольно описательной частью, а параметры до такой степени абстрактны, что именование их большой помощью читателю кода не является.
Но, с другой стороны, не только же из функторов и прочих моноидов состоят программы, поэтому в коде, более близком к прикладным вопросам решения задачи (если она сама по себе не из области аля ТК), имена параметров, скорее всего, имели бы смысл.
achmed wrote:
> MZ>(lambda (x y) (max x y)) > Пожалуй да, длинные имена в данном случае не уместны, > но буквы то все равно выбираются осознано . Вряд ли бы Вынаписали так: > > (lambda (a r) (max a r))
Да брось ты. Тут имена переменных могут быть вообще любыми.
Я часто ловлю себя на мысли (ну или ситуации), что слишком
долго думаю о имени переменной, и в итоге набираю
что-то типа
Здравствуйте, achmed, Вы писали:
A>Угу, что означают буквы c, k?
Буквой К,k а иногда C,c часто обозначают continuation — функцию, которой передают результат вычисления. "K" в начале, это , я так понимаю из немецкого.
instance Monad (State s) where
return a = State dontChangeStateAndReturnA
where dontChangeStateAndReturnA s = (a, s)
-- r1 :: State s a = State (s -> (a, s)) - это вычисление с состоянием
-- p :: a -> State s b = a -> State (s -> (b, s)) - это вычисление
-- с состоянием, зависящее от параметра, вычисляемого r1.
(State r1) >>= p = State passState
where passState s = (res2, finalState)
-- Запускаем первое вычисление, получаем параметр
where (res1, intermediateState) = r1 s
-- Вычисляем по параметру второе вычисление
(State r2) = p res1
-- Запускаем второе вычисление
(res2, finalState) = r2 intermediateState
data SM a = SM (S -> (a,S)) -- Монадический тип
instance Monad SM where
-- определяет распространение состояния
SM c1 >>= fc2 = SM (\s0 -> let (r,s1) = c1 s0
SM c2 = fc2 r in
c2 s1)
return k = SM (\s -> (k,s))
achmed wrote: > Почему программируя на функциональных языках люди дают имена переменным > из одной буквы?
> Что знают другие чего не знаю я?
Видимо, то, что на функциональных языках программы компактные,
и там НЕ НУЖНО давать "говорящее" имя переменной, потому что
весь текст программной единицы виден перед глазами, где переменная
"объявляется", и где используется.
Например, в лямбдах -- маленьких встроенных фукнциях, определяемых
по месту использования, бессмысленно давать параметрам какие-то
сложные имена -- весь код в одной строке перед глазами.
Код Жени максимально широко откомментирован и преследует цели обучения, а код из GIH взят из статьи Вадлера, в которой эта монада собственно и была впервые придумана. Для сравнения: в современной версии GHC этот код выглядит так
instance Monad (State s) where
return a = State $ \s -> (a, s)
m >>= k = State $ \s -> let
(a, s') = runState m s
in runState (k a) s'
Здравствуйте, achmed, Вы писали:
A>Добрый день!
A>Почему программируя на функциональных языках люди дают имена переменным из одной буквы?
A>Символ " ' " часто используют, это производное значение?
' используют, потому что можно. Для сравнения, в других языках можно было бы заиспользовать локальную name_ внутри функции name.
Односимвольные переменные, потому что зачастую функция занимает 2-3 строки, зачем там давать имя headOfSomeList, если место введения этой переменной всегда перед глазами? Говорящее название нужно, когда три экрана прокрутил, и вот перед глазами переменная, а фиг поймешь, к чему она относится.
А если у вас вводится (h:t), то и так ясно, что это голова и хвост соответствующего параметра.
Я честно пытался прочитать первый из этих примеров. И не смог. Оказалось, что промежуточных, никому не нужных переменных такое количество, что я вынужден постоянно держать в голове цепочку "так, эта переменная получается из этой, а та из вот этой..." Функция начинает напоминать речь Горбачёва, который и сам к концу фразы забывал, с чего она началась.
А "штрих" используется как его используют все математики — для обозначения значения, которое почти такое же в каком-то смысле, но не совсем.
Здравствуйте, Кодёнок, Вы писали:
Кё>Здравствуйте, achmed, Вы писали:
A>>Что знают другие чего не знаю я?
Кё>Математику — это в основном общепринятые обозначения оттуда.
Здравствуйте, thesz, Вы писали:
A>>Почему программируя на функциональных языках люди дают имена переменным из одной буквы?
T>Вот кусок реального кода: T>
Нуу, можно x1:x2:x3:x4:xs или так не принято?
T>Там, где логика посложней, там у меня и названия понормальней.
T>State monad не такая уж и сложная вещь после того, как разберёшься.
Ага, но разбираться все таки проще с длинными именами было.
Здравствуйте, MasterZiv, Вы писали:
MZ>achmed wrote: >> Почему программируя на функциональных языках люди дают имена переменным >> из одной буквы?
>> Что знают другие чего не знаю я?
MZ>Видимо, то, что на функциональных языках программы компактные, MZ>и там НЕ НУЖНО давать "говорящее" имя переменной, потому что MZ>весь текст программной единицы виден перед глазами, где переменная MZ>"объявляется", и где используется.
И в сигнатурах функций имен параметров тоже нет.
Вот яркий пример
callCC :: ((a -> m b) -> m a) -> m a
MZ>Например, в лямбдах -- маленьких встроенных фукнциях, определяемых MZ>по месту использования, бессмысленно давать параметрам какие-то MZ>сложные имена -- весь код в одной строке перед глазами.
MZ>(lambda (x y) (max x y))
Пожалуй да, длинные имена в данном случае не уместны,
но буквы то все равно выбираются осознано . Вряд ли бы Вынаписали так:
Здравствуйте, deniok, Вы писали:
D>Код Жени максимально широко откомментирован и преследует цели обучения, а код из GIH взят из статьи Вадлера, в которой эта монада собственно и была впервые придумана. Для сравнения: в современной версии GHC этот код выглядит так
Это интересно
D>
D>instance Monad (State s) where
D> return a = State $ \s -> (a, s)
D> m >>= k = State $ \s -> let
D> (a, s') = runState m s
D> in runState (k a) s'
D>
Непонятно, почему здесь используется k, а не f, например?
Здравствуйте, VoidEx, Вы писали:
VE>Здравствуйте, achmed, Вы писали:
A>>Добрый день!
A>>Почему программируя на функциональных языках люди дают имена переменным из одной буквы?
A>>Символ " ' " часто используют, это производное значение?
VE>' используют, потому что можно. Для сравнения, в других языках можно было бы заиспользовать локальную name_ внутри функции name.
Но ведь подчеркивание тоже можно, почему его не используют?
VE>Односимвольные переменные, потому что зачастую функция занимает 2-3 строки, зачем там давать имя headOfSomeList, если место введения этой переменной всегда перед глазами? Говорящее название нужно, когда три экрана прокрутил, и вот перед глазами переменная, а фиг поймешь, к чему она относится. VE>А если у вас вводится (h:t), то и так ясно, что это голова и хвост соответствующего параметра.
Это выражение конечно же понятно, еще такое именование часто встречаентся(x:xs), почему не пишут одинаково везде?
Здравствуйте, achmed, Вы писали:
T>>И как ты предлагаешь назвать a, b, c и d?
A>Нуу, можно x1:x2:x3:x4:xs или так не принято?
Можно. И делают. Чего никто не делает, так это не даёт им имена типа "длинныйМнемоническийИдентификатор1"
A>Ага, но разбираться все таки проще с длинными именами было.
Здравствуйте, achmed, Вы писали:
A>Пожалуй да, длинные имена в данном случае не уместны, A>но буквы то все равно выбираются осознано . Вряд ли бы Вынаписали так:
A>
(lambda (a r) (max a r))
Зависит от. Иногда и пишут, например:
instance Functor ((,) x) where fmap f (a, r) = (a, f r)
Здравствуйте, achmed, Вы писали:
A>Но ведь подчеркивание тоже можно, почему его не используют?
Непонятно. А если бы использовали подчёркивание, ты бы спросил "почему не штрих"?
A>Это выражение конечно же понятно, еще такое именование часто встречаентся(x:xs), почему не пишут одинаково везде?
Ну, наверное, потому что все люди разные. И писать одинаково не могут. Что к лучшему.
Здравствуйте, MigMit, Вы писали:
MM>Здравствуйте, achmed, Вы писали:
A>>Пожалуй да, длинные имена в данном случае не уместны, A>>но буквы то все равно выбираются осознано . Вряд ли бы Вынаписали так:
A>>
(lambda (a r) (max a r))
MM>Зависит от. Иногда и пишут, например:
MM>
instance Functor ((,) x) where fmap f (a, r) = (a, f r)
Здравствуйте, deniok, Вы писали:
D>Опасные вопросы задаёшь D>Потому, что это k не произвольная функция, а штука с типом k :: a -> m b; каждому пижону известно, что это называется стрелка Клейсли:
Гугл показывает ресурсы с упоминанием теории категорий, видимо это и есть опасность
Здравствуйте, VoidEx, Вы писали:
VE>Здравствуйте, achmed, Вы писали:параметры стало понятно
A>>И в сигнатурах функций имен параметров тоже нет. A>>Вот яркий пример A>>
A>>callCC :: ((a -> m b) -> m a) -> m a
A>>
VE>А как вы предлагаете называть произвольный тип и монаду? VE>sourceType, targetType и anyMonad?
Имелись в виду не названия типов параметров, и не названия переменных типов параметров,
а имена параметров функций, которые можно увидеть только в определении функции.
Для чего служат эти параметры становится понятно после прочтения комментариев Cont, но определения этой функции нет в исходниках.
Здравствуйте, achmed, Вы писали:
A>Имелись в виду не названия типов параметров, и не названия переменных типов параметров, A>а имена параметров функций, которые можно увидеть только в определении функции.
По-моему если для хаскельной функции тебе необходимы имена параметров, то или у тебя неправильная декомпозиция на функции или она обозвана некорректно. В идеале должно быть достаточно имени и типов. А для некоторых — всего лишь типа.
A>Для чего служат эти параметры становится понятно после прочтения комментариев Cont, но определения этой функции нет в исходниках.
Т.е. ты жалуешься на то, что в типе сигнатуре не объясняется что такое продолжения и монады?
T>>И как ты предлагаешь назвать a, b, c и d? A>Нуу, можно x1:x2:x3:x4:xs или так не принято?
И в чём будет глубокий смысл, пардоньте? Ведь можно же и так: (highestBit:lowestBitFromTwoHghest:highestBitFromLowerPair:lowestBitOfTheNibble:xs. Так ведь ещё понятней будет.
T>>State monad не такая уж и сложная вещь после того, как разберёшься. A>Ага, но разбираться все таки проще с длинными именами было.
Возьми, да перепиши по своему. Это поспособствует пониманию. Я вполне серььёзно говорю, ведь тебе придётся выразить краткую запись во многих словах, таким образом, понять смысл и выразить по своему.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Здравствуйте, thesz, Вы писали:
A>>Ага, но разбираться все таки проще с длинными именами было.
T>Возьми, да перепиши по своему. Это поспособствует пониманию. Я вполне серььёзно говорю, ведь тебе придётся выразить краткую запись во многих словах, таким образом, понять смысл и выразить по своему.
Переписал уже, причем только одна переменная с длинным именем получилась.
Я ожидал что есть какой то гайд, где расписаны рекомендации и мотивации к именованию переменных.
Здравствуйте, achmed, Вы писали:
A>Имелись в виду не названия типов параметров, и не названия переменных типов параметров, A>а имена параметров функций, которые можно увидеть только в определении функции.
С этим согласен, отсутствие имён в декларации иногда напрягает.
Заводить же
type NameOfFoo = String
type TypeOfFoo = String
type FooID = Int
foo :: NameOfFoo -> TypeOfFoo -> [FooID]
лишь для того, чтобы указать имя, как-то напряжно
Я бы предпочёл иметь возможность написать
Здравствуйте, Курилка, Вы писали:
К>Здравствуйте, achmed, Вы писали:
A>>Имелись в виду не названия типов параметров, и не названия переменных типов параметров, A>>а имена параметров функций, которые можно увидеть только в определении функции.
К>По-моему если для хаскельной функции тебе необходимы имена параметров, то или у тебя неправильная декомпозиция на функции или она обозвана некорректно. В идеале должно быть достаточно имени и типов.
Что такое CPS имел представление, о монадах кое какое представление имел. Как CPS использовать с монадами стало понятно только после прочтения комментариев.
К>А для некоторых — всего лишь типа.
Если бы этот прувер еще по названию мог функцию с нужным кодом строить
A>>Для чего служат эти параметры становится понятно после прочтения комментариев Cont, но определения этой функции нет в исходниках.
К>Т.е. ты жалуешься на то, что в типе сигнатуре не объясняется что такое продолжения и монады?
Видимо это привычка после мейнстримовых языков: где у каждого параметра есть имя, которое является самодокументируемым.
Хотя не совсем понятно какие были бы имена для callCC.
Здравствуйте, achmed, Вы писали:
A>Почему программируя на функциональных языках люди дают имена переменным из одной буквы? A>Символ " ' " часто используют, это производное значение?
потому что при коротком определении в 2-3 строчки этого вполне достаточно. твой же "расширенный" пример более понятен не из-за имён переменных, а из-за комментариев. попробуй без них..
Здравствуйте, lomeo, Вы писали:
L>Здравствуйте, achmed, Вы писали:
A>>Но ведь подчеркивание тоже можно, почему его не используют?
L>Потому что rock'n'roll круче, чем rock_n_roll.
Подозреваю, что одна из причин это ширина символа.
Здравствуйте, MigMit, Вы писали:
MM>Здравствуйте, achmed, Вы писали:
A>>Подозреваю, что одна из причин это ширина символа.
MM>У тебя в редакторе не моноширинный шрифт?