Praca z ciągami znaków w F # jest czasem nieco niewygodne. Prawdopodobnie użyłbym tego samego kodu co Dario. Gramatyka F # nie zezwala na używanie konstruktorów jako funkcji pierwszej klasy, więc niestety nie można wykonać całego przetwarzania w jednym potoku. Zasadniczo można używać elementów statycznych i metod instancji jako funkcji pierwszej klasy, ale nie właściwości instancji lub konstruktorów.
W każdym razie istnieje naprawdę nieprzyjemna sztuczka, której można użyć do przekształcenia konstruktora w wartość funkcji. Nie polecam właściwie go używać, ale byłem bardzo zaskoczony, aby zobaczyć, że to rzeczywiście działa, więc pomyślałem, że może warto dzielić go:
let inline ctor< ^R, ^T
when ^R : (static member ``.ctor`` : ^T -> ^R)> (arg:^T) =
(^R : (static member ``.ctor`` : ^T -> ^R) arg)
ten definiuje funkcję, która zostanie włączonych w czasie kompilacji, która wymaga, aby pierwszy parametr type miał konstruktor, który przyjmuje wartość parametru drugiego typu. Jest to określone jako ograniczenie podczas kompilacji (ponieważ generics .NET nie może tego wyrazić). Ponadto F # nie pozwala na określenie tego przy użyciu zwykłej składni do określania ograniczeń konstruktora (która musi przyjąć unit
jako argument), ale można użyć skompilowanej nazwy konstruktorów. Teraz można napisać na przykład:
// just like 'new System.Random(10)'
let rnd = ctor<System.Random, _> 10
rnd.Next(10)
I można również użyć wyniku ctor
jako pierwszej klasy funkcji:
let chars = [ 'a'; 'b'; 'c' ]
let str = chars |> Array.ofSeq |> ctor<System.String, _>
Jak powiedziałem, myślę, że jest to przede wszystkim ciekawość, ale całkiem ciekawy :-).
OK, ograniczenie to ma sens z punktu widzenia wydajności (tworzenie lambda, która jest prawdopodobnie trudno zoptymalizować dala prawdopodobnie mogą zranić wydajności w sposób, który jest trudny do wykryć). Każdy wskaźnik, dlaczego "nowy" jest opcjonalny? Czy tworzenie obiektów poprzez odbicie lepiej komponuje się ze składnią Ocaml/F #? Dzięki! –
Trudno wybrać jedną z odpowiedzi, wybiorę tę, ponieważ odwołuje się do innego pokrewnego pytania. :-) –
"Wygląda na to, że konstruktory obiektów nie są kompozycyjne, więc nie można ich przekazać jako funkcji." To się ostatecznie zmienia. https://github.com/fsharp/FSharpLangDesign/blob/master/FSharp-4.0/ClassNamesAsFunctionsDesignAndSpec.md – Endrju