LINUX.ORG.RU

List in ocaml


0

0

Доброго времени суток. Подскажите пожалуйста как в

         let lines_list = [] in

			      let f element =
				    let elem = element in
				    if ( elem = "AAA" ) then(
				     let tmp_lines_list = lines_list in 
				    lines_list = elem :: tmp_lines_list
				    
				    )
				else(
				  ...
				)
				in

				  List.iter f lines
lines - это List. Цель - нужно сравнить все элементы lines с «ААА» и если он равен AAA то добавить его в lines_list.
Тот код который я написал - этого не делает.
Подскажите как правильно это написать.
Заранее огромное спасибо.
(сори за простой вопрос - только недавно начел осваивать ocaml)

Ответ на: комментарий от arhibot

задача описана не целеком, а частично. В действительности ставниваеть нужно не сам элемент списка а его преобразование. так что

List.filter не подойдет. нужно как то эту логику переделать что бы оно работало коректно. заранее огромное спасибо

virvdova
() автор топика

Отставить императивные штучки

И задачу надо формулировать верно

(*
Комбинатор для функций. Смысл ясен из типа. В стандартной библиотеке его вроде нет.
( % ) : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b
*)
let (%) f g x = f (g x)

(* Тут и примененние фукнции и фильтр *)
let lines_list f xs = List.filter (((=) "AAA") % f) xs

P.S. Окамля не знаю

Shimuuar
()
Ответ на: комментарий от virvdova

Этого чтоли хочешь:
[code=ocaml]
let rec filtermap p f x acc= match x with
[] -> List.rev acc
| h::t -> match p h with
true -> filtermap p f t ((f h)::acc)
| _ -> filtermap p f t (acc)
;;
[/code]

filtermap (fun x -> x mod 2 =1 ) (fun x->x*x) [1;2;3;4;5;6;7;8;9;10] [];;
- : int list = [1; 9; 25; 49; 81]

PS. ocaml тоже не знаю

arhibot
()
Ответ на: комментарий от arhibot

Этого чтоли хочешь:

let rec filtermap p f x acc= match x with
[] -> List.rev acc
| h::t -> match p h with
true -> filtermap p f t ((f h)::acc)
| _ -> filtermap p f t (acc)
;;

filtermap (fun x -> x mod 2 =1 ) (fun x->x*x) [1;2;3;4;5;6;7;8;9;10] [];; - : int list = [1; 9; 25; 49; 81]

PS. ocaml тоже не знаю

arhibot
()
Ответ на: комментарий от arhibot

А, прочитал не правильно постановку. Но я думаю поправишь сам уж

arhibot
()
Ответ на: комментарий от virvdova

>В действительности ставниваеть нужно не сам элемент списка а его преобразование.

Я, видимо, чего то не понимаю в этой жизни. List.filter (fun x -> f x = something) lst. Преобразование сравнивается? Да. Почему не подходит?

arhibot
()
Ответ на: комментарий от virvdova

(сори за простой вопрос - только недавно начел осваивать ocaml)

Вот только ты совсем не «начел» его осваивать. Тебе в прошлом сообщении дали ссылки на кучу литературы. Если бы погуглил, узнал бы, что половина DAOC худо-бедно на русский переведена. SICP переведен полностью и хорошо.

Тот код, что ты написал в этот раз, гораздо хуже даже прошлого. Показывает, что не понимаешь базовых вещей. Зачем тогда пытаться писать? Ты же не будешь спрашивать на LOR, как написать каждую вторую функцию? А разъяснения в прошлом посте, как видно, понимания не прибавили, прибавят ли разъяснения этого? Может все-таки почитаешь что-нибудь?

И да, на OCaml стоит пытаться писать в функциональном стиле.

Ладно, без лирики...

задача описана не целеком, а частично. В действительности ставниваеть нужно не сам элемент списка а его преобразование.

  let t = String.uppercase                    (* преобразование *)
  let p x = x = "AAA"                         (* предикат *)

Самое простое решение «в лоб»:

  let rec pfilter p f = function
      []     -> []
    | h :: t -> if p (f h) then h :: pfilter p f t else pfilter p f t

Решение с хвостовой рекурсией:

  let pfilter p f l =
    let rec pf_aux accu = function
        []     -> List.rev accu
      | h :: t -> if p (f h) then pf_aux (h :: accu) t else pf_aux accu t
    in pf_aux [] l

«Однострочник», как любят хаскелисты (определены два вспомогательных оператора, отсутствующих в OCaml):

  let ( & ) f g = fun x -> f (g x)
  let ( |> ) x f = f x

  let pfilter p f l =
    List.combine l (List.map t l) |> List.filter (p & snd) |> List.map fst

Любая из этих функций работает так, как надеюсь ты ожидаешь (если я понял правильно):

  # pfilter p t ["aAa"; "bbB"; "Ccc"; "dDD"; "AaA"] ;;
  - : string list = ["aAa"; "AaA"]
satanic-mechanic
()
Ответ на: комментарий от satanic-mechanic

огромное спасибо за помощь. ( я уже начал читать DAOC, просто еще не могу привыкнуть к идеям функциональных языков програмирования - всегда хочу свести все в императивную логику.)

virvdova
() автор топика
Ответ на: комментарий от virvdova

не могу привыкнуть к идеям функциональных языков програмирования

так может с них и стоило бы начать?

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

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

dave ★★★★★
()
Ответ на: комментарий от dave

Опять же мое ИМХО, уже озвученное: проще и быстрее SICP. Дело в том, что Scheme сам по себе гораздо проще Haskell, и при этом в этой книге сам язык не рассматривается, просто по ходу вводятся необходимые для понимания и решения задач конструкции. Поэтому императивного кода не попишешь, а уровень доступен для понимания даже интересующемуся школьнику.

satanic-mechanic
()
Ответ на: комментарий от satanic-mechanic

SICP - хорошая книга. На нее очень многие ссылаются. К тому же есть перевод. Вполне вариант.

Как я понимаю, тут главная задача состоит в том, чтобы человек сначала прочитал что-то, а потом начал бы спрашивать на форуме, а не наоборот :)

dave ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.