Вопрос о совпадении F # - PullRequest
       3

Вопрос о совпадении F #

2 голосов
/ 18 февраля 2011

вот что у меня есть:

type u = {str : string} //some type that has some property str (for simplicity, only one)
type du=
   | A of u
   | B of u // some discriminated union that carries u with it

тогда, где-то у меня есть последовательность du, которую я делаю DifferentBy, и свойство делать разные - str. лучшее, что я мог придумать, это:

Seq.distinctBy (fun d -> match d with (A u|B u) -> u.str)

код работает, но мне не нравится совпадение по a и b распознаваемого объединения, и я хотел бы заменить совпадение чем-то.

вопрос в том, что? :)

РЕДАКТИРОВАТЬ:

в моем случае a и b различимого объединения всегда будут иметь с собой один и тот же тип u, одно из решений - избавиться от du и добавить его строковую форму для ввода u и упростить весь этот беспорядок, но я бы хотел пока держите это так, потому что я собирался делать матчи и тому подобное на а и б ...

Ответы [ 3 ]

5 голосов
/ 18 февраля 2011

Как насчет того, чтобы сделать совпадение один раз как свойство du?

type u = {str : string}

type du =
    | A of u
    | B of u with
    member this.U =
        match this with
        (A u | B u) -> u

[A {str="hello"}; B {str="world"}; A {str="world"}]
|> Seq.distinctBy (fun x -> x.U.str)

//val it : seq<du> = seq [A {str = "hello";}; B {str = "world";}]

Однако у меня есть пара идей, которые могут лучше моделировать отношения между вами и du, удовлетворяя при этом ваши проблемы "РЕДАКТИРОВАНИЯ".Одним из способов является просто использование кортежей:

type u = {str : string}

type du =
    | A
    | B

//focus on type u
[A, {str="hello"}; B, {str="world"}; A, {str="world"}]
|> Seq.distinctBy (fun (_,x) -> x.str)
//val it : seq<du * u> = seq [(A, {str = "hello";}); (B, {str = "world";})]

//focus on type du
let x = A, {str="hello"}
match x with
| A,_ -> "A"
| B,_ -> "B"
//val it : string = "A"

Другой способ - переключить его и добавить du к u:

type du =
    | A
    | B

type u = { case : du; str : string}

//focus on type u
[{case=A; str="hello"}; {case=B; str="world"}; {case=A; str="world"}]
|> Seq.distinctBy (fun x -> x.str)
//val it : seq<u> = seq [{case = A;
//                        str = "hello";}; {case = B;
//                                          str = "world";}]

//focus on type du
let x = {case=A; str="hello"}
match x with
| {case=A} -> "A"
| {case=B} -> "B"
//val it : string = "A"
2 голосов
/ 18 февраля 2011

Я немного новичок в F #, но, надеюсь, это поможет.Мне кажется, что активные шаблоны могут упростить вашу жизнь, если вы попытаетесь сократить то, что вам нужно ввести при сопоставлении с шаблоном.Вместо использования A a |B b вы можете использовать активный шаблон AorB вместо него.

type u = { str : string }

type du = 
    | A of u
    | B of u

let (|AorB|) (v:du) =
    match v with
        | A a -> a
        | B b -> b

[A { str = "A" }; B { str = "B"}; A { str = "A"}]
    |> Seq.distinctBy (fun d -> 
                    match d with 
                        | AorB s -> s)
    |> Seq.iter (fun i -> match i with AorB c -> printfn "%s" c.str)

С добавлением Стивена, окончательное выражение может быть написано таким образом.

2 голосов
/ 18 февраля 2011

Вы действительно не можете упростить это столько, сколько вы описываете, но вы можете упростить это. Спасибо @Tomas Petricek

[ A { str = "A" }; B { str = "B" }; B { str = "B" } ] 
|> Seq.distinctBy (fun (A u | B u) -> u.str) 
|> Seq.toArray;;

выход

[| A {str = "A";}; B {str = "B";} |]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...