А кстати можно так написать?
h :: Int -> Int
h x + 1 = x
h 3 == 2
Правило вывода сработает?
Ну это я таким извращённым способом операцию декремента реализую. Теоретически.
Понятно, что можно написать напрямую:
h x = x - 1
но мне интересна внутренняя природа устройства правил вывода.
UPDATE. На вопрос я вроде бы нашёл ответ - в pattern matching'е участвуют не функции, а конструкторы. Поправьте, если я не прав.
h :: Int -> Int
h x + 1 = x
h 3 == 2
Правило вывода сработает?
Ну это я таким извращённым способом операцию декремента реализую. Теоретически.
Понятно, что можно написать напрямую:
h x = x - 1
но мне интересна внутренняя природа устройства правил вывода.
UPDATE. На вопрос я вроде бы нашёл ответ - в pattern matching'е участвуют не функции, а конструкторы. Поправьте, если я не прав.
До hs2010 такие паттерны работали, потом их убрали из стандарта.
ОтветитьУдалитьА чем это поможет узнать внутреннею природу сопоставления с образцом в haskell?
Это поможет понять масштаб "надувательства" под капотом.
УдалитьЕщё пример:
Sqrt x * x = x
Sqrt 9 == 3
Сработает?
Сопоставление с образцом нужно для разбора ADT на составляющие;
Удалить[a] это тип с двумя конструкторами(в терминологии hs) a : [a] и a. Можно сделать свой List, он будет выглядеть так: data List a = List a (List a) | End
Тогда map с pattern matching'ом для него будет выглядеть так:
map' :: (a -> b) -> List a -> List b
map' _ End = End
map' f (List x xs) = List (f x) (map' f xs)
P.S [a] это специальное название для типа 'список', нельзя называть свои типы используя квадратные скобки. А вот конструкторы могут выглядеть как операторы, но должны начинаться на ':'. Например:
data List a = a :+ List a | End
Понятно. Спасибо.
ОтветитьУдалитьЯ примерно что-то так и думал. Что там где-то должны конструкторы участвовать.
Конструкторы, но к императивному миру они отношения не имеют. В c++/java нет аналогичных конструкций
УдалитьОй ну конечно...
УдалитьТе же самые конструкторы. ;)
Ок. Как на C++ будет выглядить тип data List a = List a (List a) | End с аналогичными конструкторами?
Удалить"Подвох" ведь заключается только в End.
УдалитьНо очевидно, что задача легко решается. Введением в каждом экземпляре ссылки на тип данных.
Подвох в том, что конструкторы в haskell и в c++ это не аналогичные конструкции
УдалитьОднако реализованы они на c++
УдалитьАга.
С таким же успехом можно утверждать что конструкции js идентичны с конструкциями C++/Java/любого языка на котором реализован интерпретатор js. Это ни о чем не говорит.
УдалитьПонимание конструкторов hs как конструкторов c++ будет только мешать изучению языка.
Поверьте, я понимаю отличия конструкторов Haskell и конструкторов C++. ;)
УдалитьИ понимаю, что такое data MyEnum = One | Two | Tree.
УдалитьИ чем оно отличается от enum в c++.
Я даже сам такое реализовал в своих скриптах. Оказывается...
УдалитьИ что такое data MyData = MyData Int.
УдалитьИ что такое data MyData = MyData Int | NullValue.
И даже понимаю что означает:
Удалитьdata Patient = Patient { firstName :: String
, lastName :: String
, email :: String
}
Это как понимать отличия между теплым и мягким. =)
УдалитьИнтересно, как на ваших скриптах будет, например: xs = 1 : map (*2) xs
ОтветитьУдалитьИмеете в виду:
Удалитьf x:xs = 1 : map (*2) xs
?
Или я что-то не так понял?
f x:xs = 1 : map (*2) xs
УдалитьВыглядит так:
LIST FUNCTION f
IN aList
ANY VAR Head
LIST VAR Tail
aList .Split Head Tail
LIST:Make 1 Map ( 2 * ) Tail
>>> Result
;
"xs = 1 : map (*2) xs" это "xs = 1 : map (*2) xs".
ОтветитьУдалитьmain = print (take 10 xs)
>>>[1,2,4,8,16,32,64,128,256,512]
А ну тем более всё просто.
УдалитьХороший пример генрации бесконечной последовательности.
УдалитьВесь день над ним думал.
Не буду врать - сейчас на моих скриптах это "в лоб" не делается. Только через "хоккей" типа CaptureContext.
Но я уже придумал как это сделать так же элегантно как и в Haskell.
Реализую - напишу.
На основе того, что написано тут:
Удалитьhttp://programmingmindstream.blogspot.ru/2017/10/haskell-vs-count.html?m=1
Ваш пример у меня выглядит так:
List def xs
List:Make:
1
( call.me ( 2 * ) List:Map )
; // List:Map
Я честно скажу - не проверял, но должно сработать. Завтра проверю.
А map разве не к отдельным элементам применяется? Как у вас степени двойки получаются?
УдалитьУ меня только так получается:
f n = n : f n * 2
xs = f 1
xs = 1 : map (* 2) (1 : map (* 2) (1 : map (* 2) (1 : map (* 2) (1 : map (* 2) [1]))))
Удалитьxs = 1 : map (* 2) (1 : map (* 2) (1 : map (* 2) (1 : map (* 2) [1,2])))
xs = 1 : map (* 2) (1 : map (* 2) (1 : map (* 2) [1, 2, 4]))
xs = 1 : map (* 2) (1 : map (* 2) [1, 2, 4, 8])
xs = 1 : map (* 2) [1, 2, 4, 8, 16]
xs = [1, 2, 4, 8, 16, 32]
Не совсем очевидно. Попробую переосмыслить.
УдалитьВ общем у меня это выглядит так:
УдалитьList def xs
List:
1
^@( call.me ( 2 * ) .List:Map )
>>> Result
; // xs
Даже вот так:
УдалитьList def xs
1 :List: ^@( xs ( 2 * ) .List:Map )
; // xs
Проверил. Работает.
УдалитьНе то чтобы я хотел написать своё подобие Haskell. Это - жалкие потуги были бы.
Мне было интересно понять как это устроено. И опробовать на примере.
Чтобы возможно начать применять Haskell обладая пониманием.
UPDATE. На вопрос я вроде бы нашёл ответ - в pattern matching'е участвуют не функции, а конструкторы. Поправьте, если я не прав.
УдалитьЯ протрассировал:
Удалитьxs = 1 : map (*2) xs
По шагам.
И вроде понял Как оно работает.
Только в терминологии haskell xs это константа, а не функция(морфизм).
УдалитьЕсли говорить вашим языком, то паттерн матчинг(и деструктивное описание) это такая магия компилятора, которая генерируется по структуре ADT. Никакие конструкторы в императивном понимании тут не участвуют(конечно, можно генерировать подобную магию и по иперативным конструкторам, как например в scala; Но там конструктор подразумевает описание структуры. А в C++/delphi/java конструктор это функция для инициализации полей, так что это не полные аналоги)
Ну да.
УдалитьТолько никакая не магия. А вполне себе формальное сопоставление. Грубо говоря кортежей. Фактический кортеж сопоставляется с тем, который в паттерн матчинге записан.
И после этого сопоставления и получаются "константы".
Сопоставление с образцом это сопоставление с образцом, вот так новости :D
УдалитьСнобизм и щёконадувательство детектед...
УдалитьОфицер? Разве ирония == снобизм?
УдалитьИзвините.
УдалитьЯ попытался объяснить как я понял механизм паттерн матчинга.
Извините пожалуйста ещё раз за наезд не по делу.
УдалитьВы на самом деле мне ОЧЕНЬ ПОМОГЛИ. Я нашёл ОЧЕНЬ проблемную инверсию в своём императивном коде. СПАСИБО!
УдалитьОЧЕНЬ ПОМОГЛИ со своим примером:
Удалитьxs = 1 : map (*2) xs
Я начал его экстраполировать на свой императивный код и нашёл опрелелённые "дыры". Где была очень глубокая рекурсия при освобождении объектов и связанных с ними данных.
СПАСИБО Вам!
Нашёл ошибку, которую уже лет пять не мог поймать.