/// 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 и @. это снижает его скорость к сожалению
plus k l1 l2 = [ take k (x ++ y) | x <- l1, y <- l2 ]
ОтветитьУдалитьplus k l1 l2 = [ take k (x ++ y) | x <- l1, y <- l2 ]
ОтветитьУдалитьдаже не скомпилируется, если l1 и l2 - List\Set, которые мне нужны - это первое. такое возможно для Seq, а Seq мне тут совсем не нужен.
второе - требуется к каждому элементу из l1 добавить каждый элемент из l2 и взять первые k символов.
третье - использование <- несколько дурной стить на мой взгляд, т.к. отступает от чистого функционального стиля, чего я стараюсь избегать по возможности на F#
п.с. возможно вы написали код на Haskell? тогда вполне возможно, что он скомпилируется и заработает(я хаскелем особо не интересуюсь, т.к. хочу иметь .Net со всем его разнообразием языков и возможностей под рукой).
ОтветитьУдалитькстати спасибо за идею использования такой формы генерации списка.
ОтветитьУдалить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) ]
немного изменённый код, так на первый взгляд более оптимально будет
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