Re: Ocaml
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 15.08.13 06:05
Оценка: 92 (7) :))) :))) :))) :))) :))
Здравствуйте, Aleksandr_KPI, Вы писали:

A_K>Подскажите, как реализовать инверсию списков и под-списков в Ocaml.


О, это совсем просто! Список — это рекурсивный индуктивный тип, а значит получается как инициальный объект в категории F-алгебр определенного функтора. В данном случае функтора F(X) = 1 + A*X. Опишем понятие функтора в категории, он состоит из двух отображений: первое отображает объекты категории (типы), второе — морфизмы (функции).
module type Functor = sig 
  type 'a t 
  val fmap : ('a -> 'b) -> 'a t -> 'b t 
end


Чтобы получить инициальную алгебру, нам понадобится неподвижная точка этого функтора. Для произвольного эндофунктора получить его неподвижную точку можно так:
module Fix(F : Functor) = struct
    type t = Fx of t F.t   (*  t = Fix f  *)
    let unfix (Fx x) = x 
end


Инициальная алгебра характеризуется тем, что из нее существует уникальный гомоморфизм в любую другую алгебру на том же функторе. В категории алгебр данного функтора это катаморфизм. Определяется он так:
module Alg(F : Functor) = struct
  let rec cata : ('a F.t -> 'a) -> Fix(F).t -> 'a =
    fun alg ff -> 
      let module FixF = Fix(F) in
      alg (F.fmap (cata alg) (FixF.unfix ff))
end


Это получился всем знакомый fold, в случае списков это foldr, но описанная функция работает как свертка для любых функторов, не только списков. Имея такую свертку, определить переворачивание списков — уже дело техники. Сперва опишем функтор F(X)=1+A*X, задающий F-алгебру списка. Чтобы из такого простого функтора сделать рекурсивный тип, мы потом применим оператор неподвижной точки.
module type Type = sig type t end

type ('a, 'b) lst = Nil | Cons of 'a * 'b

module ListF(A:Type) : Functor with type 'a t = (A.t, 'a) lst =
struct
  type 'a t = (A.t, 'a) lst

  let fmap f = function 
    | Cons(a,b) -> Cons(a, f b)
    | Nil -> Nil 
end


А теперь опишем алгебру-разворачиватель, и передадим ее в катаморфизм списка, чтобы получить функцию разворота списка:
let id x = x

module Reverse(A:Type) = struct
  module AListF = ListF(A)
  module AList = Fix(AListF)
  module AListAlg = Alg(AListF)
  type builder = AList.t -> AList.t

  let alg : builder AListF.t -> builder  = function
    | Nil -> id
    | Cons(a, b) -> fun x -> b (AList.Fx (Cons(a, x)))

  let rev xs = AListAlg.cata alg xs (AList.Fx Nil)
end;;

Вот и все! Проверяем. Возьмем список целых чисел, построим, развернем и выведем:
module Int = struct type t = int end

let module R = Reverse(Int) in
let mylist =
  let open R.AList in 
  let cons a b = Fx (Cons(a,b)) in 
  cons 1 (cons 2 (cons 3 (Fx Nil))) in
  let result = R.rev mylist in
  let show = function Nil -> "[]" | Cons(a,b) -> Printf.sprintf "(%d, %s)" a b in
  print_string (R.AListAlg.cata show result);;

Ocaml
От: Aleksandr_KPI  
Дата: 14.08.13 08:59
Оценка:
Подскажите, как реализовать инверсию списков и под-списков в Ocaml.

Заранее благодарю за ответ.
Re[2]: Ocaml
От: Aleksandr_KPI  
Дата: 15.08.13 11:45
Оценка:
Здравствуйте, D. Mon, Вы писали:

оверквотинг удалён, разметка добавлена

Очень благодарен Вам за пример, но я новичок в Ocalm и приведенный Вами код мне трудно понять.

Я думаю решить поставленную задачу можно с помощью функции List.rev.

# let l = [1; 5; 2];;
val l : int list = [1; 5; 2]
# List.rev l ;;
- : int list = [2; 5; 1]
#


Только я не знаю как задать подсписок в Ocaml. Писал пробовал, но не вышло. Не факт еще, что функция List.rev l будет с ним работать.

let r = [15; [1;4]; 1] ;;
               ^^^^^
Error: This expression has type 'a list
       but an expression was expected of type int



Прошу Вас помочь мне с моими вопросами или, если у Вас найдется время и желание, описать подробно как работает Ваш код. Синтаксис Ocalm читаю 3 день, но пока он труден для меня.

Заранее благодарю.
Re[2]: Ocaml
От: Кодт Россия  
Дата: 15.08.13 12:22
Оценка:
Здравствуйте, D. Mon, Вы писали:

DM>О, это совсем просто!


В высокой науке слова "нетрудно показать, что" означают свёртку примерно 50 страниц выкладок.
Перекуём баги на фичи!
Re[3]: Ocaml
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 15.08.13 12:30
Оценка:
Здравствуйте, Aleksandr_KPI, Вы писали:

A_K>Я думаю решить поставленную задачу можно с помощью функции List.rev.


Конечно. Просто было неясно: то ли спрашивает студент, которому нужно самому List.rev реализовать, то ли что.

A_K>Только я не знаю как задать подсписок в Ocaml. Писал пробовал, но не вышло. Не факт еще, что функция List.rev l будет с ним работать.


A_K>let r = [15; [1;4]; 1] ;;

A_K> ^^^^^
A_K>Error: This expression has type 'a list
A_K> but an expression was expected of type int

А тут конпилятор всю правду уже сообщил. В списке все элементы должны быть одного типа, так уж списки устроены. А у вас первый элемент — число, а второй — список. Нельзя просто так взять и положить в список элементы разных типов. Потому и неясно было, что именно подразумевается под подсписками. Вот если весь список состоит из списков, например, [1;2], [3;4]], то их можно все развернуть, применив List.rev к каждому элементу: List.map List.rev xs.

Однако очень рекомендую почитать вот этот учебник:
http://caml.inria.fr/pub/docs/oreilly-book/html/index.html
Re[3]: Ocaml
От: Кодт Россия  
Дата: 15.08.13 12:42
Оценка:
Здравствуйте, Aleksandr_KPI, Вы писали:

A_K>Только я не знаю как задать подсписок в Ocaml. Писал пробовал, но не вышло. Не факт еще, что функция List.rev l будет с ним работать.

A_K>
A_K>let r = [15; [1;4]; 1] ;;
A_K>               ^^^^^
A_K>Error: This expression has type 'a list
A_K>       but an expression was expected of type int
A_K>


Ну правильно. Список — это контейнер элементов одного типа. Например, int. Или, int list. Но не вперемешку.
Надо сперва уточнить, что имеется в виду под "подсписком".
— гомогенная двухуровневая структура — список списков чисел
— гетерогенная двухуровневая структура — список чисел и списков чисел
— гетерогенное дерево — список чисел и вложенных списков
И затем — пояснить, как должен работать реверс. Только верхнего яруса, только второго яруса, или только яруса перед листьями, каждого яруса?

A_K>Прошу Вас помочь мне с моими вопросами или, если у Вас найдется время и желание, описать подробно как работает Ваш код. Синтаксис Ocalm читаю 3 день, но пока он труден для меня.


Димон издевается. Надо ещё спасибо сказать, что он заехал только сверху, с алгебр. А мог и снизу, с комбинаторной логики и голого лямбда-исчисления жахнуть.
Перекуём баги на фичи!
Re[4]: Ocaml
От: Aleksandr_KPI  
Дата: 15.08.13 14:07
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Aleksandr_KPI, Вы писали:


A_K>>Только я не знаю как задать подсписок в Ocaml. Писал пробовал, но не вышло. Не факт еще, что функция List.rev l будет с ним работать.

A_K>>
A_K>>let r = [15; [1;4]; 1] ;;
A_K>>               ^^^^^
A_K>>Error: This expression has type 'a list
A_K>>       but an expression was expected of type int
A_K>>


К>Ну правильно. Список — это контейнер элементов одного типа. Например, int. Или, int list. Но не вперемешку.

К>Надо сперва уточнить, что имеется в виду под "подсписком".
К>- гомогенная двухуровневая структура — список списков чисел
К>- гетерогенная двухуровневая структура — список чисел и списков чисел
К>- гетерогенное дерево — список чисел и вложенных списков
К>И затем — пояснить, как должен работать реверс. Только верхнего яруса, только второго яруса, или только яруса перед листьями, каждого яруса?

A_K>>Прошу Вас помочь мне с моими вопросами или, если у Вас найдется время и желание, описать подробно как работает Ваш код. Синтаксис Ocalm читаю 3 день, но пока он труден для меня.


К>Димон издевается. Надо ещё спасибо сказать, что он заехал только сверху, с алгебр. А мог и снизу, с комбинаторной логики и голого лямбда-исчисления жахнуть.


Примет требуемого реверса:

Исходный список: [3; [5; 2; 7]; 1; 8]
Требуемый результат: [8; 1; [7; 2; 5]; 3]

Про функцию List.map я читал, читал так же что нельзя создавать списки с разным типом элементов, но нигде не могу найти информацию по подспискам. Как и можно ли их вообще создавать, так как я привел в примере выше.

Благодарю за ответы.
Re[5]: Ocaml
От: Кодт Россия  
Дата: 15.08.13 14:26
Оценка:
Здравствуйте, Aleksandr_KPI, Вы писали:

A_K>Примет требуемого реверса:


A_K>Исходный список: [3; [5; 2; 7]; 1; 8]

A_K>Требуемый результат: [8; 1; [7; 2; 5]; 3]

A_K>Про функцию List.map я читал, читал так же что нельзя создавать списки с разным типом элементов, но нигде не могу найти информацию по подспискам. Как и можно ли их вообще создавать, так как я привел в примере выше.


Это не про функцию надо читать, а про систему типов.
В ML она более сурова и справедлива, чем в каком-нибудь лиспе или питоне.

Нужно сперва создать тип, объединяющий скаляры и списки.
type 'a MyItem = Single of 'a
               | Many of 'a list
               ;;

let revertItem x = match x with
| Single y -> x
| Many ys -> Many ...
;;

let revertAll xs = List.rev (List.map revertItem xs) ;;  (* или наоборот, сперва обращаем верхний уровень, а потом каждый элемент *)

a = [Single 3; Many [7;2;5]; Single 1; Single 8];;
b = revertAll a;;

Или, если данные многоуровневые, то
type 'a MyData = Single of 'a | Many of ('a MyData) list ;;

let rec revertAll data = match x with
| Single y -> x
| Many xs -> Many ...
;;

a = Many [Single 3; Many [Single 7; Single 2; Single 5]; Single 1; Single 8];;
b = revertAll a;;
Перекуём баги на фичи!
Re[6]: Ocaml
От: Aleksandr_KPI  
Дата: 16.08.13 11:13
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Aleksandr_KPI, Вы писали:


A_K>>Примет требуемого реверса:


A_K>>Исходный список: [3; [5; 2; 7]; 1; 8]

A_K>>Требуемый результат: [8; 1; [7; 2; 5]; 3]

A_K>>Про функцию List.map я читал, читал так же что нельзя создавать списки с разным типом элементов, но нигде не могу найти информацию по подспискам. Как и можно ли их вообще создавать, так как я привел в примере выше.


К>Это не про функцию надо читать, а про систему типов.

К>В ML она более сурова и справедлива, чем в каком-нибудь лиспе или питоне.

К>Нужно сперва создать тип, объединяющий скаляры и списки.

К>
К>type 'a MyItem = Single of 'a
К>               | Many of 'a list
К>               ;;

К>let revertItem x = match x with
К>| Single y -> x
К>| Many ys -> Many ...
К>;;

К>let revertAll xs = List.rev (List.map revertItem xs) ;;  (* или наоборот, сперва обращаем верхний уровень, а потом каждый элемент *)

К>a = [Single 3; Many [7;2;5]; Single 1; Single 8];;
К>b = revertAll a;;
К>

К>Или, если данные многоуровневые, то
К>
К>type 'a MyData = Single of 'a | Many of ('a MyData) list ;;

К>let rec revertAll data = match x with
К>| Single y -> x
К>| Many xs -> Many ...
К>;;

К>a = Many [Single 3; Many [Single 7; Single 2; Single 5]; Single 1; Single 8];;
К>b = revertAll a;;
К>



Большое спасибо за код Хотел бы прояснить пару моментов.
Насколько я понял использовать в названии типа заглавные буквы нельзя, пишет ошибку: "Error: Syntax error". В примерах из книг тоже такого не видел, но и не читал о таком правиле.

Что касается следующей части кода:
let revertItem x = match x with
| Single y -> x
| Many ys -> Many ...
;;


Вот тут со второй частью функции выбора не понятно. Если в списке попадается подсписок, так его указать, писал [], Many [] .... все не правильно.

a = Many [Single 3; Many [Single 7; Single 2; Single 5]; Single 1; Single 8];;
b = revertAll a;;

Списки у меня так почему то не задаются, нужно писать let a = .... let b = ... иначе ошибка: "Error: Unbound value a"

Заранее благодарю за ответы.
Re[7]: Ocaml
От: Кодт Россия  
Дата: 16.08.13 23:12
Оценка:
Здравствуйте, Aleksandr_KPI, Вы писали:

A_K>Большое спасибо за код Хотел бы прояснить пару моментов.

A_K>Насколько я понял использовать в названии типа заглавные буквы нельзя, пишет ошибку: "Error: Syntax error". В примерах из книг тоже такого не видел, но и не читал о таком правиле.

Начнём с того, что я не настоящий погонщик верблюдов, и сварочную маску только на стройке нашёл. Поэтому в синтаксисе путаюсь. (Тем более, что диалекты ML расходятся в синтаксисе).
Так что учить язык буду вместе с тобой. (Если оно нам надо, конечно).

Окей, пусть имена типов будут в кемелКейсе, а Капс только для конструкторов типов или для модулей и функторов.
Ну и let x = ... — это связывание переменной, а x = ... — это булево выражение, проверка на равенство.

В этом плане диалоговый интерпретатор — полезная штука. Вводишь — ругается — вводишь заново — начинаешь понимать, чего он хочет.
Перекуём баги на фичи!
Re[2]: Ocaml
От: Кодт Россия  
Дата: 17.08.13 19:47
Оценка:
Здравствуйте, D. Mon, Вы писали:

DM>О, это совсем просто!


Решил-таки вчитаться в твою святую простоту.
Возникли вопросы.

DM>
DM>module type Functor = sig ....
DM>module Fix(F : Functor) = struct ....
DM>


Теоркатовский функтор здесь — абстрактный модуль, а неподвижная точка — функтор.
А нельзя как-нибудь извернуться, так, чтобы функтор был функтором? Просто, чтобы сразу впрыгнуть в категорию окамла?

DM>Инициальная алгебра характеризуется тем, что из нее существует уникальный гомоморфизм в любую другую алгебру на том же функторе. В категории алгебр данного функтора это катаморфизм. Определяется он так:

DM>
DM>module Alg(F : Functor) = struct
DM>  let rec cata : ('a F.t -> 'a) -> Fix(F).t -> 'a =
DM>    fun alg ff -> 
DM>      let module FixF = Fix(F) in
DM>      alg (F.fmap (cata alg) (FixF.unfix ff))
DM>end
DM>

Зачем сделал аннотацию типа функции? Он там сам выводится, казалось бы.

DM>
DM>module ListF(A:Type) : Functor with type 'a t = (A.t, 'a) lst = struct .....
DM>

Зачем здесь with type?


DM>А теперь опишем алгебру-разворачиватель, и передадим ее в катаморфизм списка, чтобы получить функцию разворота списка:


Как-то ты бодро перескочил через абстрактные анаморфизмы, и сразу приступил к конкретному — разворачивателю.
Или я что-то путаю?
Перекуём баги на фичи!
Re[8]: Ocaml
От: Aleksandr_KPI  
Дата: 17.08.13 19:48
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Aleksandr_KPI, Вы писали:


A_K>>Большое спасибо за код Хотел бы прояснить пару моментов.

A_K>>Насколько я понял использовать в названии типа заглавные буквы нельзя, пишет ошибку: "Error: Syntax error". В примерах из книг тоже такого не видел, но и не читал о таком правиле.

К>Начнём с того, что я не настоящий погонщик верблюдов, и сварочную маску только на стройке нашёл. Поэтому в синтаксисе путаюсь. (Тем более, что диалекты ML расходятся в синтаксисе).

К>Так что учить язык буду вместе с тобой. (Если оно нам надо, конечно).

К>Окей, пусть имена типов будут в кемелКейсе, а Капс только для конструкторов типов или для модулей и функторов.

К>Ну и let x = ... — это связывание переменной, а x = ... — это булево выражение, проверка на равенство.

К>В этом плане диалоговый интерпретатор — полезная штука. Вводишь — ругается — вводишь заново — начинаешь понимать, чего он хочет.

Без обид) Я Вам очень благодарен за код. Просто разбираюсь с ним только 3 день.


let revertItem x = match x with
| Single y -> x
| Many ys -> Many ...
;;


Подскажите что написать вместо точек, как обратится к подсписку в данном случае?

С уважением, Александр.
Re[9]: Ocaml
От: Кодт Россия  
Дата: 17.08.13 23:24
Оценка:
Здравствуйте, Aleksandr_KPI, Вы писали:

A_K>Без обид) Я Вам очень благодарен за код. Просто разбираюсь с ним только 3 день.

A_K>Подскажите что написать вместо точек, как обратится к подсписку в данном случае?

С какой целью?
Если это учебное задание, то я не хочу, как двое из ларца, "вы что, и конфеты за меня есть будете?!" — надо же что-то для самостоятельного освоения оставить.

А идея-то простая:
— лист Single y оставляем как есть
— список Many ys — извлекаем список, {извлекаем и переворачиваем каждый элемент, упаковываем в список}, переворачиваем список целиком, упаковываем в Many.

В фигурных скобках — процедура, которая требуется, если у нас предполагается более одного уровня вложенности.
Перекуём баги на фичи!
Re[3]: Ocaml
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 18.08.13 12:30
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Теоркатовский функтор здесь — абстрактный модуль, а неподвижная точка — функтор.

К>А нельзя как-нибудь извернуться, так, чтобы функтор был функтором? Просто, чтобы сразу впрыгнуть в категорию окамла?

То, что в окамле обзывается ключевым словом functor, не слишком похоже на теоркатовский функтор, это просто параметризованный модуль. Не очень понятно, чем именно параметризовать модуль для функтора из ТК. Можно было бы модулечком Type, как ниже сделано со списком, но тогда не ясно, как описывать fmap, где два типа-параметра. А двумя модулями или одним с парой типов — тоже все некузяво выходит.

DM>> let rec cata : ('a F.t -> 'a) -> Fix(F).t -> 'a =

К>Зачем сделал аннотацию типа функции? Он там сам выводится, казалось бы.

Для понятности!

DM>>module ListF(A:Type) : Functor with type 'a t = (A.t, 'a) lst = struct .....

К>Зачем здесь with type?

Чтобы сделать внутреннее устройство 'a t публичным, иначе о том, как именно устроен 'a t, будет известно лишь внутри модуля.

К>Как-то ты бодро перескочил через абстрактные анаморфизмы, и сразу приступил к конкретному — разворачивателю.

К>Или я что-то путаю?

Это я поленился. Наверное, можно было бы там понаучнее сделать.
Re[7]: Ocaml
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 18.08.13 14:15
Оценка:
Здравствуйте, Aleksandr_KPI, Вы писали:

А вы какой учебник по окамлу читаете?

A_K>>>Примет требуемого реверса:

A_K>>>Исходный список: [3; [5; 2; 7]; 1; 8]
A_K>>>Требуемый результат: [8; 1; [7; 2; 5]; 3]

К>>Или, если данные многоуровневые, то

К>>type 'a MyData = Single of 'a | Many of ('a MyData) list ;;

Это будет как-то так:
type 'a tree = Single of 'a | Many of 'a tree list

let rec reverse = function
  | Single x -> Single x
  | Many xs -> Many (List.rev (List.map reverse xs))


И проверка:
let rec show = function
  | Single x -> string_of_int x
  | Many xs -> "(" ^ String.concat " " (List.map show xs) ^ ")";;

let lst = Many [Single 1; Many [Single 2; Single 3]; Single 4] in
print_string (show (reverse lst));;
Re[4]: Ocaml
От: Кодт Россия  
Дата: 18.08.13 15:21
Оценка:
Здравствуйте, D. Mon, Вы писали:

DM>То, что в окамле обзывается ключевым словом functor, не слишком похоже на теоркатовский функтор, это просто параметризованный модуль. Не очень понятно, чем именно параметризовать модуль для функтора из ТК. Можно было бы модулечком Type, как ниже сделано со списком, но тогда не ясно, как описывать fmap, где два типа-параметра. А двумя модулями или одним с парой типов — тоже все некузяво выходит.


Мне казалось, что на уровне модулей functor это именно функтор, отображающий содержимое параметров — типы на типы, функции на функции... модули на модули?
Хотя возможно, что система модулей в окамле недостаточно богата, чтобы сделать над ней теоркат.


DM>>>module ListF(A:Type) : Functor with type 'a t = (A.t, 'a) lst = struct .....

К>>Зачем здесь with type?

DM>Чтобы сделать внутреннее устройство 'a t публичным, иначе о том, как именно устроен 'a t, будет известно лишь внутри модуля.


А где эта публичность/приватность аукается?
В конце концов, 'a t — это не новый тип, а синоним какого-то типа, данного извне, о котором компилятор полностью осведомлён?

P.S.
Всё-таки, французы в очередной раз показали, что это нация эстетов-извращенцев. (Мало нам французской высокой кухни и французского автомобильного дизайна?) Синтаксис окамла переплёвывает по своей затейливости даже С++.
Перекуём баги на фичи!
Re[5]: Ocaml
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 18.08.13 20:57
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Мне казалось, что на уровне модулей functor это именно функтор, отображающий содержимое параметров — типы на типы, функции на функции... модули на модули?

К>Хотя возможно, что система модулей в окамле недостаточно богата, чтобы сделать над ней теоркат.

Наоборот, окамловские модули слишком мощные. Теоркатовский функтор — это две функции (одна для объектов, вторая для морфизмов), а окамловский модуль может сразу очень много типов и сложных структур отображать. Собственно, выше модуль Functor успешно реализует теоркатовский функтор, даже не будучи окамловским функтором.

DM>>>>module ListF(A:Type) : Functor with type 'a t = (A.t, 'a) lst = struct .....

К>>>Зачем здесь with type?
DM>>Чтобы сделать внутреннее устройство 'a t публичным, иначе о том, как именно устроен 'a t, будет известно лишь внутри модуля.
К>А где эта публичность/приватность аукается?

Вот дальше в коде мы определяем свою алгебру, где матчим по Nil и Const, но без той декларации with мы в этом месте не знаем, что у данного типа есть такие конструкторы, по которым мы пытаемся матчить, т.е. AListF.t и чего-то-там lst — разные типы.

К>P.S.

К>Всё-таки, французы в очередной раз показали, что это нация эстетов-извращенцев. (Мало нам французской высокой кухни и французского автомобильного дизайна?) Синтаксис окамла переплёвывает по своей затейливости даже С++.

Уи, мёсьё, сэ врэ.
Re[6]: Ocaml
От: Кодт Россия  
Дата: 18.08.13 21:29
Оценка:
Здравствуйте, D. Mon, Вы писали:

DM>Наоборот, окамловские модули слишком мощные. Теоркатовский функтор — это две функции (одна для объектов, вторая для морфизмов), а окамловский модуль может сразу очень много типов и сложных структур отображать. Собственно, выше модуль Functor успешно реализует теоркатовский функтор, даже не будучи окамловским функтором.


Вот только модуль — это константа (э... неужто категория?), отображение — это таки функтор модуля.
Я потому и спрашиваю: нет ли смысла и возможности сделать
module Category = sig ..... end;;
module Morphism(C:Category) = sig ... end;;
module Functor(C:Category) : Morphism = struct ... end;;

(подчёркиваю, я в окамл только по праздникам играю, поэтому могу заблуждаться).


DM>Уи, мёсьё, сэ врэ.

Не "уи", а "увы"!

Что мешало им хотя бы скобки блоков одинаково расставлять? sig...end, struct...end, let...;;, type...CRLF ?!
И из-за адского, хотя и непротиворечивого, синтаксиса у них парсер, по-видимому, тупо рекурсивный спуск делает, до первой ошибки. Которую он диагностирует как "Syntax error".
Перекуём баги на фичи!
Re[7]: Ocaml
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 19.08.13 05:21
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Вот только модуль — это константа (э... неужто категория?), отображение — это таки функтор модуля.


Внутре обычного модуля мы же можем определять типы с параметрами ('a t), а это уже ничто иное, как отображение типов. Для этого окамловский функтор не требуется. Даже больше, мы можем определять естественные преобразования (отображения функторов), вроде List.hd, которое, как и подобает ест.преобразованию есть функция из объектов одной категории в стрелки другой (из типа 'a в функцию 'a list -> 'a). Если теоркатовские функторы изображать окамловскими функторами, то чем изображать естественные преобразования? Там и слова такого уже нет.

К>Я потому и спрашиваю: нет ли смысла и возможности сделать...


Да, нет смысла.

К>Что мешало им хотя бы скобки блоков одинаково расставлять? sig...end, struct...end, let...;;, type...CRLF ?!


У let и type нет закрывающей скобки, можно прямо подряд писать. К CRLF и отступам чувствительности нет.

К>И из-за адского, хотя и непротиворечивого, синтаксиса у них парсер, по-видимому, тупо рекурсивный спуск делает, до первой ошибки. Которую он диагностирует как "Syntax error".


Кажися, там все же LR парсер а-ля yacc. Собственно, ocamlyacc входит в поставку.
Re[7]: Ocaml
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 19.08.13 06:36
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Не "уи", а "увы"!


Кстати, to add insult to injury, у окамла же целых два официальных синтаксиса есть — дефолтный и revised:
http://caml.inria.fr/pub/docs/manual-camlp4/manual007.html
Некоторые опытные камловоды предпочитают revised.

К>подчёркиваю, я в окамл только по праздникам играю


Разумеется, программирование на окамле — всегда праздник!
Re[8]: Ocaml
От: Кодт Россия  
Дата: 19.08.13 09:23
Оценка:
Здравствуйте, D. Mon, Вы писали:

DM>Кстати, to add insult to injury, у окамла же целых два официальных синтаксиса есть — дефолтный и revised:

DM>http://caml.inria.fr/pub/docs/manual-camlp4/manual007.html
DM>Некоторые опытные камловоды предпочитают revised.

Это не insult, а инфаркт!
У окамла есть ряд вкусностей — параметризованные модули, рассыпные варианты, объекты наконец.
Но подход к каждой из них словно разные люди одновременно и не сговариваясь.
А теперь ещё и ревизия, где понадёргали из фадиеза и, прости господи, из Си.

К>>подчёркиваю, я в окамл только по праздникам играю


DM>Разумеется, программирование на окамле — всегда праздник!

Ага, и выражение лица — как у того студента из приключений Шурика.
Перекуём баги на фичи!
Re[8]: Ocaml
От: Кодт Россия  
Дата: 19.08.13 09:39
Оценка:
Здравствуйте, D. Mon, Вы писали:

DM>Внутре обычного модуля мы же можем определять типы с параметрами ('a t), а это уже ничто иное, как отображение типов. Для этого окамловский функтор не требуется. Даже больше, мы можем определять естественные преобразования (отображения функторов), вроде List.hd, которое, как и подобает ест.преобразованию есть функция из объектов одной категории в стрелки другой (из типа 'a в функцию 'a list -> 'a). Если теоркатовские функторы изображать окамловскими функторами, то чем изображать естественные преобразования? Там и слова такого уже нет.


А внутри одного типа мы можем вообще без параметризованных типов обойтись, будут экземпляры типа, функции над ним и функции высшего порядка.
А внутри одного значения будет id, id, id

Т.е. вниз мы двигаться умеем. А окамл даёт возможность двигаться и вверх, вводя модули и стрелки над модулями.

К>>Я потому и спрашиваю: нет ли смысла и возможности сделать...

DM>Да, нет смысла.
Да нет наверное

К>>Что мешало им хотя бы скобки блоков одинаково расставлять? sig...end, struct...end, let...;;, type...CRLF ?!


DM>У let и type нет закрывающей скобки, можно прямо подряд писать. К CRLF и отступам чувствительности нет.

У let есть ;;, а у type — любой терминальный символ, который не может встретиться в объявлении типа.
type foo = bla bla bla bla bla bla type bar = .....
         (                         )


К>>И из-за адского, хотя и непротиворечивого, синтаксиса у них парсер, по-видимому, тупо рекурсивный спуск делает, до первой ошибки. Которую он диагностирует как "Syntax error".

DM>Кажися, там все же LR парсер а-ля yacc. Собственно, ocamlyacc входит в поставку.

Ну да, но работает он тупо, до первой звезды.
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.