2010-03-10 19 views
13

Konsoldan printfn işlevine benzer bir okuma işlevi olup olmadığını bilen var mı? Şimdiye kadar gördüğüm tek yöntem, System.Console.Read() kullanıyor ama printfn gibi bir yapı kullanmak kadar işlevsel değil.F # Konsolundan Oku #

cevap

16

Gerçekten de böyle bir yerleşik işlev olmadığı konusunda utanç vericidir. Ancak, Brian Benjol'un cevabına yaptığı bir yorumda belirttiği gibi, bir scanf işlevini kendiniz oluşturmak mümkündür. Sadece %s tutucuları uygulanmasına rağmen Burada biri sscanf varyantını tanımlamak nasıl hızlı bir kroki, var:

open System 
open System.Text 
open System.Text.RegularExpressions 
open Microsoft.FSharp.Reflection 

let sscanf (pf:PrintfFormat<_,_,_,_,'t>) s : 't = 
    let formatStr = pf.Value 
    let constants = formatStr.Split([|"%s"|], StringSplitOptions.None) 
    let regex = Regex("^" + String.Join("(.*?)", constants |> Array.map Regex.Escape) + "$") 
    let matches = 
    regex.Match(s).Groups 
    |> Seq.cast<Group> 
    |> Seq.skip 1 
    |> Seq.map (fun g -> g.Value |> box) 
    FSharpValue.MakeTuple(matches |> Seq.toArray, typeof<'t>) :?> 't 


let (a,b) = sscanf "(%s, %s)" "(A, B)" 
let (x,y,z) = sscanf "%s-%s-%s" "test-this-string" 
+7

Daha fazla ihtiyacım olduğunda 'sscanf' sürümü, bu kodu genişletmek oldukça kolaydı. Buradaki sonuca bakın: http://fssnip.net/4I – wmeyer

+0

@wmeyer - Bu harika! – kvb

+0

@wmeyer: FSharpx'e katkıda bulunmak ister misiniz? https://github.com/fsharp/fsharpx –

1

Bildiğim kadarıyla, hayır.

O TryParse kod golf :)

+3

O 'printfn' fonksiyon kendisi derleyici sihirli dayanan bir utanç - Kendi F #' sscanf gelemedi 'oldukça güzel. –

+4

Yapabilirsin, sanırım. Tek sihir, dize değişmezlerinin PrintfFormats'a zorlanabilmesidir, bu noktada tipler belirgindir: pf(): printfFormat <_, _, _, _> = "% d% s" – Brian