Size: a a a

2020 May 15

AV

Alexander Vershilov in fprog_spb
Примеры значений:

ЕстьДанные 3 :: M Int
ЙаСломалсо :: M Int
ЙаСломалсо :: M Bool
источник

AV

Alexander Vershilov in fprog_spb
замечу, что 2 отличается от 3 несмотря на то, что значение там очень похожее
источник

AV

Alexander Vershilov in fprog_spb
Теперь мы пишем функцию:

f :: Int -> Int -> M Int
источник

AV

Alexander Vershilov in fprog_spb
f _ 0 = ЙаСломалсо
f n m = ЕстьДанные  (div n m)
источник

AV

Alexander Vershilov in fprog_spb
Т.е. у нас 2 варианта, если передали 0 то мы сломались, если не 0 - то вернули результат
источник

AV

Alexander Vershilov in fprog_spb
Дальше делаем первый шаг, пусть у нас есть результат M Int. и мы хотим связать его пока с чистой функцией g :: Int -> Int (например (+1))
источник

AV

Alexander Vershilov in fprog_spb
введём функцию, которая за нас это сделает:

fmap :: (Int -> Int) -> M Int -> M Int
fmap g a  = ...
источник

AV

Alexander Vershilov in fprog_spb
Как это сделать, чтобы это записать компилятор нас попросит рассмотреть все случаи вариантов M которые бывают
источник

AV

Alexander Vershilov in fprog_spb
Т.е. что мы можем сделать если у нас есть (+1) и ЙаСломалсо?
источник

AV

Alexander Vershilov in fprog_spb
Очевидно, мы никак не можем применить функцию, у нас не к чему, мы можем только вернуть ЙаСломалсо
источник

AV

Alexander Vershilov in fprog_spb
А если у нас ЕстьДанные то мы можем применить функцию, и дальше или сказать ЕстьДанные (g x) или ЙаСломалсо (но второе не очень логично и кажется нарушает законы)
источник

AV

Alexander Vershilov in fprog_spb
Это функтор, чуть более простой интерфейс чем монада
источник

AV

Alexander Vershilov in fprog_spb
А с монадой тоже самое примерно, мы создаёт фукнкцию (>>=) читается как байнд (bind)
источник

AV

Alexander Vershilov in fprog_spb
(>>=) :: M a -> (a -> M b) -> M b
(>>=) =
источник

A

Andrey in fprog_spb
Александр Гранин
Переслано от Александр Гранин
Поэтому хороший программист никогда не останавливается на одном языке. В идеале, каждый должен знать по одному языку из основных направлений:

- низкоуровневый язык с ручным управлением памятью (Си, С++, Rust)
- высокоуровневый язык с управляемой (managed) памятью (Java, C#, Scala)
- динамический язык (Python, JavaScript, Clojure, Ruby)
- ООП язык (Java, C#, Ruby, C++, JavaScript)
- функциональный язык (Haskell, Scala, Clojure, Erlang)
- логический (Prolog)

И вот когда программист знает хотя бы по одному из всех категорий, он может принимать действительно взвешенные решения. Его набор инструментов очень расширяется, а изучение нового языка уже не представляет проблем.
здесь нет языков из семейства APL. когда человек столкнётся с многомерными массивами, он не сможет выбрать подходящего решения, т.к. не будет знать, что делать и выберет какие-нибудь C или Python.

> Изучение нового языка не будет проблемой

это спорное утверждение в случае семейства APL
источник

AV

Alexander Vershilov in fprog_spb
m >>= f = case m of
  ЙаСломалсо -> ЙаСломалсо
  ЕстьДанные a -> f a
источник

AV

Alexander Vershilov in fprog_spb
Т.е. если данные уже сломаны, то весь пауплайн ломается, а если есть, то результат применения второй функции
источник

AS

Alex Shipilov in fprog_spb
т.е. по типу аргумента выбирается какая функция выполниться
источник

YS

Yan Shkurinskiy in fprog_spb
Функция одна и та же
источник

YS

Yan Shkurinskiy in fprog_spb
Можно было вместо паттернов написать кейс
источник