Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [OCaml] преобразование структуры данных в строку, как правильно работать с перечислениями? 
V
    Опции темы
Kakadu
Дата 22.9.2009, 20:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 273
Регистрация: 19.3.2008

Репутация: нет
Всего: 7



Код


type logConst = True | False;;
type subjVal = SubjVal of string * bool | LogConst;;
type predicateName = PredicateName of string;;
    
type term = subjVal;;
type atomFormula = AtomFormula of predicateName * term list;;
type fip = Formula of atomFormula |  LogConst of logConst
        | BinOp of string*fip*fip;;

let t2 = BinOp ( "AND",
                 LogConst True,
                 Formula (AtomFormula (PredicateName ("P"), [ SubjVal ("a", true) ] ) ) 
                );;

let term_to_string (t:term) : string = ""
    ;;
let string_of_atomformula (af:atomFormula) =
    let ans = ref "" in
        let terms_to_string tlst = 
            List.iter (fun t -> ans := (!ans ^ ","^ (term_to_string t) )) tlst 
                  
            in 
            terms_to_string (    match af with
                                | AtomFormula (name,lst) -> lst
                );
            "AtomFormula(\""^(    match af with
                                | AtomFormula (name,lst) -> (match name with
                                                            |  PredicateName n -> n )
                ) ^"\"" ^ !ans ^ ")"
    ;;
    
let rec string_of_fip f = 
    match f with 
        | Formula af -> "Formula( " ^ (string_of_atomformula af) ^ " )"
        | LogConst lc -> ( 
                match lc with 
                    | True -> "True"
                    | False -> "False"
            )
        | BinOp (name,fip1,fip2) ->
            " ("^(string_of_fip fip1)^ " "^name^" "^(string_of_fip fip2)^") " 
    ;;

Функция string_of_atomformula это какой-то трэш. smile  Как это правильно писать?


--------------------
Добрые мариносы долго кормили украдкой маленьких зерлингов. От этой украдки зерлинги пухли и дохли
PM MAIL   Вверх
Void
Дата 22.9.2009, 21:33 (ссылка) |    (голосов:4) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 1
Всего: 173



Что ж, взглянем на эту функцию. Первое, что бросается в глаза, — это деструктивное, с присваиваниями, построение строки. Вообще, в OCaml это нормально, но в данном случае никакого выигрыша не даёт (для инкрементального построения строк надо использовать Buffer). Поэтому перепишем terms_to_string в чистом виде с использованием стандартной функции fold_left. Вообще, если из списка нам нужно сделать одно значение, это почти всегда указывает на применимость свёртки (fold).
Код
let terms_to_string = function
    | [] -> ""
    | t::ts -> List.fold_left (fun s x -> s ^ ", " ^ term_to_string x) (term_to_string t) ts

К функции явно напрашивается обобщение: списки, разделённые запятыми, можно много из чего строить. Параметризуем её функцией перевода элемента списка в строку:
Код
let comma_separated_list tostr = function
    | [] -> ""
    | t::ts -> List.fold_left (fun s x -> s ^ ", " ^ tostr x) (tostr t) ts

Стоит обратить внимание на получившийся тип:
Код
val comma_separated_list : ('a -> string) -> 'a list -> string

Если вдруг эта функция станет узким местом, можно переписать с помощью Buffer:
Код
let comma_separated_list tostr = function
    | [] -> ""
    | t::ts ->
        let b = Buffer.create 10 in
        Buffer.add_string b (tostr t);
        List.iter (fun x ->
                Buffer.add_string b ", ";
                Buffer.add_string b (tostr x))
            ts;
        Buffer.contents b

Теперь terms_to_string можно записать очень просто:
Код
let terms_to_string = comma_separated_list term_to_string (* карринг *)

Ну и наконец сама функция string_of_atomformula:
Код
let string_of_atomformula = function
    | AtomFormula(PredicateName name, terms) ->
        "AtomFormula(\"" ^ name ^ "\"" ^ terms_to_string terms ^ ")"


P.S. Темы всё-таки корректнее называть надо.

Это сообщение отредактировал(а) Void - 22.9.2009, 23:10


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
Kakadu
Дата 5.10.2009, 20:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 273
Регистрация: 19.3.2008

Репутация: нет
Всего: 7



Да. я наконец-то собрался и осмыслил это. спасибо


--------------------
Добрые мариносы долго кормили украдкой маленьких зерлингов. От этой украдки зерлинги пухли и дохли
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума «Функциональные языки: общие вопросы»
Void
  • Пожалуйста, создавайте темы с содержательными названиями. Если у Вас вопрос по конкретному языку, укажите его в заголовке, например: «[Haskell] Как использовать монаду State».
  • Уважаемые учащиеся, здесь всегда рады помочь Вам, но не делать за Вас вашу работу. У вас гораздо больше шансов получить помощь, если Вы приложите усилия и поделитесь с нами проблемами и результатами. В противном случае добро пожаловать в раздел Центр Помощи.
  • Получив ответ на интересующий Вас вопрос, не забудьте пометить его как решённый.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Void.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Функциональные языки: общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0835 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.