пятница, 19 ноября 2010 г.

Ну разве этот код не красив?...

/// L1 ⊕k L2 = {w | (w = xy, x ∈ L1, y ∈ L2, |xy| 6 k) ∨ (w = γ, xy = γβ, x ∈ L1, y ∈ L2, |γ| = k)}.
let plus k (L1 : List) (L2 : List) =
    List.fold (fun (acc : list) (x : string) ->
        (List.map (fun (y : string) -> 
                if (x.Length + y.Length) < k 
                    then x + y
                    else (x + y).Substring(0, k)
                ) L2 
            ) @ acc
        ) [] L1

хотя мне не нравится то, как пришлось использовать fold и @. это снижает его скорость к сожалению

5 комментариев:

  1. plus k l1 l2 = [ take k (x ++ y) | x <- l1, y <- l2 ]

    даже не скомпилируется, если l1 и l2 - List\Set, которые мне нужны - это первое. такое возможно для Seq, а Seq мне тут совсем не нужен.

    второе - требуется к каждому элементу из l1 добавить каждый элемент из l2 и взять первые k символов.

    третье - использование <- несколько дурной стить на мой взгляд, т.к. отступает от чистого функционального стиля, чего я стараюсь избегать по возможности на F#

    ОтветитьУдалить
  2. п.с. возможно вы написали код на Haskell? тогда вполне возможно, что он скомпилируется и заработает(я хаскелем особо не интересуюсь, т.к. хочу иметь .Net со всем его разнообразием языков и возможностей под рукой).

    ОтветитьУдалить
  3. кстати спасибо за идею использования такой формы генерации списка.

    let _plus k (l1 : list) (l2 : list) = [
    for x in l1 do
    for y in l2 ->
    if (x.Length + y.Length) < k
    then x + y
    else (x + y).Substring(0, k) ]

    немного изменённый код, так на первый взгляд более оптимально будет

    ОтветитьУдалить
  4. fold и @ можно заменить на collect.
    let plus k (L1 : string list) (L2 : string list) =
        List.collect (fun (x : string) ->
            List.map (fun (y : string) ->
                if (x.Length + y.Length) < k
                then x + y
                else (x + y).Substring(0, k)
            ) L2
        ) L1

    ОтветитьУдалить