referencing one's own class library in a F# project on VS2015 - f#

i have a solution called Algos
on Solution explorer i have 2 projects inside this solution
one called Algos (again ! maybe i should change the name for avoiding confusion ?)
which is a console application
one called MyLibrary which is a Class Library
I have in the solution explorer added in the References of the Project Algo MyLibrary and i can see it in the list.
// useful functions
// returns the minimum + index of the minimum
namespace Misc
exception InnerError of string
module Search =
let mini (s : (int*int) list) =
match s with
| [] -> (-1,(-1,-1))
| _ -> s |> Seq.mapi (fun i x -> (i, x)) |> Seq.minBy snd
let maxi (s : (int*int) list) =
match s with
| [] -> (-1,(-1,-1))
| _ -> s |> Seq.mapi (fun i x -> (i, x)) |> Seq.maxBy snd
module Bit =
let rec sumbits (n:int):int=
let rec helper acc m =
match m with
| 0 -> acc
| 1 -> acc+1 // enlever cela ?
| _ -> let r = m%2
helper (acc+r) (m>>>1)
helper 0 n
let power2 k =
let powers_of_2 = [|1;2;4;8;16;32;64;128;256;512;1024;2048;4096;8192;16384;32768;65536;131072;262144;524288;1048576;2097152;4194304;8388608;16777216|]
if ((k >= 24) || (k<0)) then raise (InnerError("power exponent not allowed"))
else powers_of_2.[k]
i'm just to use Misc.Bit.power2 in the main code
open MyLibrary
let a = Misc.Bit.power2 3
but Misc.Bit will be underlined and I have a compiler error
Severity Code Description Project File Line Suppression State
Error The value, constructor, namespace or type 'Bit' is not defined Algos C:\Users\Fagui\Documents\GitHub\Learning Fsharp\Algos\Algos\TSP.fs 50
what have i done wrong ? does it come from other parts of the source code perhaps ?
there are no other warnings.
both projects use .NET Framework 4.5.2
MyLibrary uses Target F# Runtime 4.3.1 while there is no similar indication for Algos.
thanks

Two things come to mind here: I don't see where the namespace MyLibrary is defined, and you haven't mentioned that you actually compiled the dependency.
Generally, to reference and use a library within the same solution, you need to:
add the library to the using program's dependency, preferably via: References – right-click – add Reference (Reference Manager) – Projects – Solution, by checking the checkbox of the dependency.
compile the dependency. When referenced properly, this should automatically occur before dependent code is compiled, but IntelliSense will only update after compiles! So hit compile when you see outdated errors.
use identifiers from the library via their correct namespace. Make sure that the qualified names or open declarations in the using code are correct.
To my knowledge, this should be all you need to do.
There are rare cases where files get write-locked but never released on compilation and you need to restart Visual Studio to be able to compile again. I've also encountered a case where some interaction of Git and Visual Studio created corrupted, half-deleted files with effectively no file owner; this required a reboot to fix. If you're really scratching your head and the errors are clearly nonsensical, maybe try moving the folder to check for file system damage.

This should certainly work. Please also make sure that you target same versions of F# and .NET: .NET 4.5.2 and 4.4.0.0 in the library and the console application

Related

Better way to get tree representation of directory using F#?

I am new(ish) to F# and am trying to get a tree representation of a filesystem directory. Here's what I came up with:
type FSEntry =
| File of name:string
| Directory of name:string * entries:seq<FSEntry>
let BuildFSDirectoryTreeNonTailRecursive path =
let rec GetEntries (directoryInfo:System.IO.DirectoryInfo) =
directoryInfo.EnumerateFileSystemInfos("*", System.IO.SearchOption.TopDirectoryOnly)
|> Seq.map (fun info ->
match info with
| :? System.IO.FileInfo as file -> File (file.Name)
| :? System.IO.DirectoryInfo as dir -> Directory (dir.Name, GetEntries dir)
| _ -> failwith "Illegal FileSystemInfo type"
)
let directoryInfo = System.IO.DirectoryInfo path
Directory (path, GetEntries directoryInfo)
But... pretty sure that isn't tail recursive. I took a look at the generated IL and didn't see any tail prefix. Is there a better way to do this? I tried using an accumulator but didn't see how that helps. I tried mutual recursive functions and got nowhere. Maybe a continuation would work but I found that confusing.
(I know that stack-depth won't be an issue in this particular case but still would like to know how to tackle this non-tail recursion problem in general)
OTOH, it does seem to work. The following prints out what I am expecting:
let PrintFSEntry fsEntry =
let rec printFSEntryHelper indent entry =
match entry with
| File name -> printfn "%s%s" indent name
| Directory(name, entries) ->
printfn "%s\\%s" indent name
entries
|> Seq.sortBy (function | File name -> 0 | Directory (name, entries) -> 1)
|> Seq.iter (printFSEntryHelper (indent + " "))
printFSEntryHelper "" fsEntry
This should probably be a different question but... how does one go about testing BuildFSDirectoryTreeNonTailRecursive? I suppose I could create an interface and mock it like I would in C#, but I thought F# had better approaches.
Edited: Based on the initial comments, I specified that I know stack space probably isn't an issue. I also specify I'm mainly concerned with testing the first function.
To expand on my comment from earlier - unless you anticipate working with inputs that would cause a stack overflow without tail recursion, there's nothing to be gained from making a function tail-recursive. For your case, the limiting factor is the ~260 characters in path name, beyond which most Windows APIs will start to break. You'll hit that way before you start running out of stack space due to non-tail recursion.
As for testing, you want your functions to be as close to a pure function as possible. This involves refactoring out the pieces of the function that are side-effecting. This is the case with both of your functions - one of them implicitly depends on the filesystem, the other prints text directly to the standard output.
I guess the refactoring I suggest is fairly close to Mark Seemann's points: few mocks - checked, few interfaces - checked, function composition - checked. The example you have however doesn't lend itself nicely to it, because it's an extremely thin veneer over EnumerateFileSystemInfo. I can get rid of System.IO like this:
type FSInfo = DirInfo of string * string | FileInfo of string
let build enumerate path =
let rec entries path =
enumerate path
|> Seq.map (fun info ->
match info with
| DirInfo (name, path) -> Directory(name, entries path)
| FileInfo name -> File name)
Directory(path, entries path)
And now I'm left with an enumerate: string -> seq<FSInfo> function that can easily be replaced with a test implementation that doesn't even touch the drive. Then the default implementation of enumerate would be:
let enumerateFileSystem path =
let directoryInfo = DirectoryInfo(path)
directoryInfo.EnumerateFileSystemInfos("*", System.IO.SearchOption.TopDirectoryOnly)
|> Seq.map (fun info ->
match info with
| :? System.IO.FileInfo as file -> FileInfo (file.Name)
| :? System.IO.DirectoryInfo as dir -> DirInfo (dir.Name, dir.FullName)
| _ -> failwith "Illegal FileSystemInfo type")
You can see that it has virtually the same shape as the build function, minus recursion, since the entire 'core' of your logic is in EnumerateFileSystemInfos which lives beyond your code. This is a slight improvement, not in any way test-induced damage, but still it's not something that will make it onto anyone's slides anytime soon.

Problems launching functions using continuation in Visual Studio

I'm currently trying to learn f# using the book Real-World Functional Programming by Petricek and Skeet (2010) but have been encountering problems when using continuations to avoid stack overflow.
The problem that I have been encountering is that my code using continuations works perfectly when launched in the f# interactive, but still causes stack overflow when placing the code in the program.fs file and then launching it through the debugger in Visual Studio.
It is unclear to me why this happens, and would very much appreciate if anyone could give me an explanation to why this happens.
In case the version of Visual Studio is relevant, I am using:
Visual Studio Ultimate 2012
Version 11.0.61030.00 Update 4
The .Net framework used is:
Version. 4.5.51641
The code presented in the book that is causing this problem is presented below:
open System
let rand = new Random()
//A tree is either a leaf with a value or a node that contains two children
type IntTree =
| Leaf of int
| Node of IntTree * IntTree
//A list of that will decide all leaf values
let numbers2 = List.init 1000000 (fun _ -> rand.Next(-50,51))
///Creates an imbalanced tree with 1000001 leafs.
let imbalancedTree2 =
numbers2 |> List.fold (fun currentTree num ->
Node(Leaf(num), currentTree)) (Leaf(0))
//Sums all leafs in a tree by continuation and will execute the inserted function with the total
//sum as argument once all values have been summed.
let rec sumTreeCont tree cont =
match tree with
| Leaf(num) -> cont(num)
| Node(left, right) ->
sumTreeCont left (fun leftSum ->
sumTreeCont right (fun rightSum ->
cont(leftSum + rightSum)))
//Sums the imbalanced tree using the sumTreeCont function
let sumOfTree = sumTreeCont imbalancedTree2 (fun x -> x)
Thanks in advance!
//Tigerstrom
If you are running the program in Debug mode, then the default Visual Studio project setting disables tail calls. The main reason is that, with tail calls enabled, you do not get very useful information in the call stack (which makes debugging harder).
To fix this, you can go to your project options and check "Generate tail calls" on the "Build" page. In release mode, this is enabled by default.

Using an F# type provider to instantiate types and present them as properties

I'd like to do the following:
let allTypes = AllTypes (t, assemblies)
... where AllTypes is a type provider, the properties of which are instances of all types in the given array of assemblies that subclass type t. (All of the types have a single constructor that takes no arguments.)
Is this doable using F# type providers? I have no experience creating my own provider, and I don't want to waste my time attempting to do this if it isn't feasible.
I'd greatly appreciate any links to pages that would get me started coding this.
there's a lot of activity going on in the FSharp.Data github repo. There is a learning curve, but tuning into that repo might be useful.
Beyond that, this intro tutorial covers some of the basics, and here's a Type Provider starter pack that's been prepared by the F# open source community.
The fsharp.org site, and this projects page covers a cross-section of what's going on (including type providers).
You could take the list that Mark suggests here and turn it into a type provider. I think an exploratory way of interacting with namespaces would be useful. Why not? I'd use it. Please publish on GitHub if you get around to it.
You don't need a type provider for that; you can write that code using basic reflection:
open System.Reflection
let allTypes (baseClass : Type) (assemblies : Assembly seq) =
assemblies
|> Seq.collect (fun x -> x.GetExportedTypes())
|> Seq.filter (fun x -> baseClass.IsAssignableFrom x)
|> Seq.collect (fun x -> x.GetConstructors())
|> Seq.filter (fun x -> x.GetParameters().Length = 0)
|> Seq.map (fun x -> x.Invoke([||]))
The allTypes function has this signature: Type -> Assembly seq -> obj seq.

How do you provide ResizeArray to legacy F# apps?

I'm building TrueSkill, the F# app, from 2008, on Mono 3.0 with F# 3.0. The two errors I get are
fList |> ResizeArray.iter (fun f -> f.ResetMarginals()) and
let sumLogS = fList |> ResizeArray.fold_left (fun acc f -> acc + (f.LogNormalisation ())) 0.0.
For F# 1.9, ResizeArray came from the PowerPack. Apparently there's a PowerPack on github now. But the standard Mono docs show that ResizeArray<T> is just an alias for List<T>. Do I need to get the original ResizeArray, and if so, how would I do just that from the PowerPack, using the ResizeArray.fs? What's the current relationship between List and ResizeArray?
To clarify, ResizeArray<'T> is also an alias for List<'T> in .NET. Only high-order functions from ResizeArray module are provided by F# PowerPack.
Because there is no dependency on this module, it is recommended to copy ResizeArray.fs directly to your project. You probably have to change a few function names to match the new ResizeArray module e.g. changing fold_left to fold and fold_right to foldBack.

What the period (.) does in a F# method

Sorry for the vague description, couldn't find a better way to plain it.
I'm starting with F# and like many others I'm translating my solved Euler problems to F#. I like to run my code using tests and also I like the FsUnit style. With the help of the given example I did this:
open System
open NUnit.Framework
open FsUnit
type EulerProblem() =
member this.problem1 = Seq.init 999 (fun n -> n + 1)
|> Seq.filter (fun n -> n % 3 = 0 || n % 5 = 0)
|> Seq.sum
[<TestFixture>]
type ``Given an Euler problem`` () =
let euler = new EulerProblem()
[<Test>] member test.
``when I try to solve #1 should return [the magic number]`` ()=
euler.problem1 |> should equal [the magic number]
This works, but I cannot understand what the period after the test method does. If I take it away the compiler complaints saying:
This instance member needs a parameter to represent the object being invoked. Make the member static or use the notation 'member x.Member(args)
Sorry if this is trivial, and maybe i'm not using the correct wording but couldn't get an answer with google.
Thanks
If you are familiar with C#, or Java, or C++, you can refer to a class instance using the this reserved word within instance members. In F#, you must explicitly give a name to the class instance for each member definition and in the FsUnit example, the name given is merely test but it's not actually used. You could just the same have written the test method as
[<Test>] member this.
``when I try to solve #1 should return [the magic number]`` ()=
euler.problem1 |> should equal [the magic number]
But note that these days, both xUnit.net and NUnit allow applying their [<Fact>] and [<Test>] attributes respectively for marking tests on let bound functions within modules and without needing TestFixtures and such, which is much better suited for F#. So, for example, the test you gave can and in my opinion ought to be written as:
module EulerProblemTests () =
[<Test>]
let ``when I try to solve #1 should return [the magic number]`` () =
let euler = new EulerProblem()
euler.problem1 |> should equal [the magic number]
Moreover, you probably don't want to create your problem solutions as members of a type like EulerProblem, rather as functions within a module.
It's still a Class, so each member has to be static, or have a "this" defined.
In your test "test" is the "this" for the member.
Normally the class would look like this:
type ClassName() =
member thisname.MethodName() =
DoSomeStuff |> DoMoreStuff
With the period, the word "test" was being used, without it it doesn't know what kind of member it is.

Resources