2016-10-04 8 views
7

मैं कई मौखिक अभिव्यक्ति है कि मैं एक समारोह में पैक किया है:एफ # में "कयामत की पिरामिड" से छुटकारा

open FsVerbalExpressions 
open FsVerbalExpressions.VerbalExpression 
open System.Text.RegularExpressions 
open System 

let createOrVerbExFromList (verbExList: VerbEx list) = 
    let orVerbEx = 
     verbExList 
     |> List.reduce (fun acc thing -> verbExOrVerbEx RegexOptions.IgnoreCase acc thing) //simpleVerbEx 

    orVerbEx 

let k12VerbEx =  
    let kTo12 = ["SCHOOL"; "DIST"; "SD"; "HS"; "BD OF ED"] 
    kTo12 
    |> List.map (fun word -> VerbEx(word)) 
    |> createOrVerbExFromList 

let twoYearCollegeVerbEx = 
    VerbEx("2 Year College") 

let universityVerbEx = 
    VerbEx("UNIV") 

let privateSchoolVerbEx = 
    VerbEx("ACAD") 

//Here there be dragons: 
let newInst (x: string) = 
    match (isMatch x k12VerbEx) with 
    | true -> "K - 12" 
    | _ -> match (isMatch x twoYearCollegeVerbEx) with 
      | true -> "2 Year College" 
      | _ -> match (isMatch x universityVerbEx) with 
        | true -> "University" 
        | _ -> match (isMatch x privateSchoolVerbEx) with 
          | true -> "Private/Charter School" 
          | _ -> "Other" 

मैं newInst समारोह को फिर से लिखने के लिए करना चाहते हैं, जिससे कि अब या "विनाश का पिरामिड। मेरा सवाल यह है कि मैं विनाश के पिरामिड से कैसे छुटकारा पा सकता हूं? मैं इससे छुटकारा पा सकता हूं? मुझे संदेह है कि यह async वर्कफ़्लो या अन्य कम्प्यूटेशनल अभिव्यक्ति का कुछ प्रकार होगा, लेकिन वे सभी बहुत मेरे लिए नया।

उत्तर

16

यदि y कहां केवल बूलियन्स के खिलाफ मिलान कर रहे हैं, तो if ... elif पर्याप्त है:

let newInst (x: string) = 
    if isMatch x k12VerbEx then 
     "K - 12" 
    elif isMatch x twoYearCollegeVerbEx then 
     "2 Year College" 
    elif isMatch x universityVerbEx then 
     "University" 
    elif isMatch x privateSchoolVerbEx then 
     "Private/Charter School" 
    else 
     "Other" 

एक और अधिक लचीला संभावना एक सक्रिय पैटर्न बनाने के लिए होगा:

let (|IsMatch|_|) f x = 
    if isMatch x f then Some() else None 

let newInst (x: string) = 
    match x with 
    | IsMatch k12VerbEx -> "K - 12" 
    | IsMatch twoYearCollegeVerbEx -> "2 Year College" 
    | IsMatch universityVerbEx -> "University" 
    | IsMatch privateSchoolVerbEx -> "Private/Charter School" 
    | _ -> "Other" 
+0

यह सक्रिय पैटर्न के लिए एक महान परिचय था। क्या आप मुझे सक्रिय पैटर्न में अतिरिक्त '| _' का महत्व बता सकते हैं? – Steven

+2

'| _' आंशिक सक्रिय पैटर्न इंगित करता है, जिसका अर्थ है कि यह सभी मानों से मेल नहीं खा सकता है (यही कारण है कि यह एक विकल्प देता है)। [दस्तावेज़ीकरण देखें] (http://stackoverflow.com/documentation/f%23/962/active-patterns/23523/complete-and-partial-active-patterns#t=201610041942173049847) कुल और आंशिक एपी के बीच अंतर के बारे में । आपके मामले में आप वास्तव में कुल एपी लिखना चाहते हैं, लेकिन इसका कार्यान्वयन स्वयं ही विनाश के समान पिरामिड के अधीन होगा :) – Tarmil

3

जब वास्तव में कोड का एक ही रूप के अनुक्रमिक पुनरावृत्ति होती है , मैं बजाय एक डेटा-आधारित दृष्टिकोण का उपयोग करना पसंद:

let verbExStrings = 
    [ 
     (k12VerbEx, "K - 12") 
     (twoYearCollegeVerbEx, "2 Year College") 
     (universityVerbEx, "University") 
     (privateSchoolVerbEx, "Private/Charter School") 
    ] 

let newInst x = 
    verbExStrings 
    |> List.tryPick (fun (verbEx, string) -> if isMatch x verbEx then Some string else None) 
    |> function Some x -> x | _ -> "Other" 

इस दृष्टिकोण का एक लाभ यह है कच्चे डेटा (verbExStrings) मैं आ सकता है कि n अन्य स्थानों में आसान है और आपके कोड कार्यान्वयन से बंधे नहीं है।

संबंधित मुद्दे