0

I want to use this function let CopyDir target source filterFile ...(line 219) and specify a filter. The idea is that the filter will contains files which will be excluded. Right now I am using a string value log4net and it is working but I want to replace it with nugetDependencies which is a collection of strings. Would you help me pls

let nugetDependencies = getDependencies "./packages.config" let excludeNuget (path : string) = path.Contains "log4net" |> not CopyDir nugetToolsDir (buildDir @@ package) excludeNuget

UPDATE:
Fixed wrong URL

mynkow
  • 4,408
  • 4
  • 38
  • 65

2 Answers2

3

I had to read the question a few times to understand it. My understand is that you want to filter a list of file paths by a list of exclusions--with "log4net" being an example of an exclusion.

I'd go something like this, taking advantage of List.exists:

let excludePaths (pathsToExclude : string list) (path: string) =
    pathsToExclude |> List.exists (fun exPath -> path.Contains(exPath)) |> not

This implementation can actually curry the labda function fun exPath -> path.Contains(exPath) into simply path.Contains since the method takes a single argument, which would give us:

let excludePaths (pathsToExclude : string list) (path: string) =
    pathsToExclude |> List.exists path.Contains |> not

Currying (the F# formal term is partial application) can also be put to use here to bind an argument to the function. To create a check for "log4net", you can simply do this:

let nugetExclusions = ["log4net"]
let excludeNuget = excludePaths nugetExclusions 

Just add all of the nuget paths you need to exclude from the list.


Since you are comparing paths contains doesn't have a case-insensitive overload. At least not out of the box. You can add an extension function to string, though. A C# implementation is here on SO.

Here's a F# implementation of the extension method (note that I made this with a small-case contains--F# functions and overloads don't mix):

type System.String with 
    member x.contains (comp:System.StringComparison) str = 
        x.IndexOf(str,comp) >= 0

With this type extension in place we can change the excludePaths function to this (again, I'm currying the newly created contains extension method:

let excludePaths (pathsToExclude : string list) (path: string) =
    pathsToExclude 
        |> List.exists (path.contains StringComparison.OrdinalIgnoreCase)) 
        |> not

I hope you continue to use F#.

Community
  • 1
  • 1
Christopher Stevenson
  • 2,843
  • 20
  • 25
  • It took me 5 hours to flatten the nugetDependencies because it was a collection of tuples. Now everything works. thank you. – mynkow Aug 22 '14 at 00:15
  • 1
    +1, but terminology quibble: "Curry" is commonly misunderstood; it is not the same as partial application. Rather, currying is the process of converting a function that takes multiple arguments to a function that takes a single argument and returns another function (which in turn takes one argument, etc.). In other words, currying is the concept that allows partial application. I also note that passing path.Contains to List.exists is neither currying nor partial application; it's just passing a function as an argument to a function. – phoog Aug 22 '14 at 20:57
  • Gotcha, but partial application was used to make the function that was passed as an argument, right? (I didn't bind the partially bound `path.Contains StringComparison.OrdinalIgnoreCase` to a name, though.) – Christopher Stevenson Oct 11 '14 at 06:06
1

How about this?

let excludeNuget (path : string) =
    nugetDependencies
    |> Seq.exists (fun x -> path.Contains x)
Mark Seemann
  • 225,310
  • 48
  • 427
  • 736