Showing posts with label F#. Show all posts
Showing posts with label F#. Show all posts

Thursday, September 15, 2011

F# type providers: oData from NuGet

Yesterday F# 3.0 Developer Preview  became available at the MSDN Site. It will be general available on Friday.

One of the new features is the type provider.

This little snippet shows how easy it is to query a site that provides oData. NuGet is an example of a site that provides oData.

Code Snippet
  1. #r "FSharp.Data.TypeProviders.dll"
  2. #r "System.Data.Services.Client.dll"
  3.  
  4. open Microsoft.FSharp.Data.TypeProviders
  5.  
  6. [<Generate>]
  7. type NuGet = ODataService<"http://packages.nuget.org/v1/FeedService.svc/">
  8.  
  9. let dbNuGet = NuGet.GetDataContext()
  10. let packages = dbNuGet.Packages
  11.  
  12. let nuGetQuery =
  13.     query { for package in packages do
  14.             where (package.Tags.Contains("fsharp") && package.IsLatestVersion)
  15.             select package }
  16.  
  17. let printPackage (package:NuGet.ServiceTypes.PublishedPackage) =
  18.     printfn "- - - - - - - - - - - - - - - - - - - -"
  19.     printfn "Title: %s" package.Title
  20.     printfn "Authors: %s" package.Authors
  21.     printfn "Description: %s" package.Description
  22.  
  23.     
  24. nuGetQuery |> Seq.iter printPackage

This is the result:

result

One of the nice features of type providers is intellisense for the available types.

intellisense

It is possible to create your own type provider.

More information will be available on Friday. Don Syme will present all the details at build: http://channel9.msdn.com/events/BUILD/BUILD2011/SAC-904T

update: Writing F# Type Providers with the F# 3.0 Developer Preview - An Introductory Guide and Samples

Thursday, September 1, 2011

Monads for .NET developers

I have written an article for the Dutch developer magazine of SDN (Magazine 111). It is titled: “Monads voor de .NET-ontwikkelaar”.

In this post I will list some of the available resources on monads for .NET developers:

C# resources

Books:

Web:

F# resources

Computation Expressions are addressed in most of the available F# books (Professional F# 2.0 does not): F# and functional programming

Web:

Presentations

Some theory

Code:

The source code of the article: MonadsVoorDeDotNetOntwikkelaar and MonadsVoorDeDotNetOntwikkelaar_english

Thursday, August 4, 2011

Adding xml strings in F# using computation expressions

In some cases types are enhanced wrappers of simple types. For instance in .NET:

  • DateTime is a point in time and provides, among others things, extra functionality related to representing date and time formats.
  • XElement is an xml string and provides, among others things, checks to determine the validity of the xml string.
  • Option can contain a value and can tell you if there is value available.

Sometimes you have to deal with underling type and reuse some of the functionality of the wrapper. In this case you could consider using computation expressions.

This is a simple xml example. We create a xmlBuilder and reuse the validation logic of XElement:

open System
open System.Xml
open System.Xml.Linq

type xmlBuilder()=
member x.Bind(el:XElement,(f:string -> XElement)) =
try
f(el.ToString())
with
| :? XmlException as exc -> XElement.Parse(String.Format("<XmlException>{0}</XmlException>", exc.Message))
member x.Return(text) =
try
XElement.Parse(text)
with
| :? XmlException as exc -> XElement.Parse(String.Format("<XmlException>{0}</XmlException>", exc.Message))

The string “123” creates an error:
let xml = new xmlBuilder()

let error =
xml {
return "123"
}
val error : XElement = <XmlException>Data at the root level is invalid. Line 1, position 1.</XmlException>

The expression can now be used to reuse sting functions:

let toUpper el =
xml {
let! x = el
return x.ToUpper()
}

let el = XElement.Parse("<a><b>1</b><b>2</b></a>")
let result1 = el |> toUpper

val result1 : XElement = <A>
<B>1</B>
<B>2</B>
</A>

In the same way we can define a simple add function for xml:

let (+) (el1:XElement) (el2:XElement) =
xml {
let! x1 = el1
let! x2 = el2
return x1.Substring(0, x1.LastIndexOf("<")) + x2.Substring(x2.IndexOf(">") + 1)
}

let el1 = XElement.Parse("<a><b>1</b><b>2</b></a>")
let el2 = XElement.Parse("<a><b>3</b><b>4</b></a>")
let result2 = el1 + el2

val result2 : XElement =
<a>
<b>1</b>
<b>2</b>
<b>3</b>
<b>4</b>
</a>

let el3 = XElement.Parse("<c><b>3</b><b>4</b></c>")
let result3 = el1 + el3

val result3 : XElement = <XmlException>The 'a' start tag on line 1 position 2 does not match the end tag of 'c'. Line 7, position 3.</XmlException>
This may not be in line with the concept of information hiding, but it can help you in case you have to deal with the simple type to get the work done.

Tuesday, June 28, 2011

WTF is a Monad by Robert C. Martin in F#

I have read some material describing Computation Expressions and knew computation expressions are the F# implementation of monads, but I did know why one should use a monad.

A few days ago saw the video of presentation by Robert C. Martin (Uncle Bob) at the Norwegian Developers Conference called “WTF is a Monad” and now it makes sense to me.

It is a proven way of solving problems. If you:

  • have a problem in one domain
  • you can transform it to another domain
  • solve the problem in the other domain
  • and can transform it back

you have a solution.

I have translated some of the code of the presentation to F#. I tried to stay as close to the original code as possible and did not do much refactoring. I skipped the last two examples (distributions an state).

Update: I did not implement the examples that required lift. I have not figured out how to do that. I have created the lift myself (details: http://bugsquash.blogspot.com/2010/12/notes-on-haskell-functors-and-f.html)

I like to thank Robert for the permission to share the code. Feel free to add improvements in the comments.

//Non-Monadic dots

let dotsToN (d:string) =
d.Length

let result1 = dotsToN "....."

let nToDots (n:int) =
new string('.', n)

let result2 = nToDots 5

let addDots da db =
let a = dotsToN da
let b = dotsToN db
nToDots (a+b)

let result3 = addDots "..." "..."

//Monadic dots

let dotResult = nToDots

let dotBind d (f:int -> string) =
d |> dotsToN |> f

let addDots' da db =
dotBind da (fun a ->
dotBind db (fun b ->
dotResult (a + b)))

let result4= addDots' "..." "..."

//dot-Monad
type dotBuilder()=
member x.Bind(d,(f:int -> string)) = d |> dotsToN |> f
member x.Return(n) = new string('.', n)

let dot = new dotBuilder()

let addDots'' da db =
dot { let! x = da
let! y = db
return x + y
}

let result5= addDots'' "..." "..."

let multiplyDots da db =
dot { let! x = da
let! y = db
return x*y
}

let result6= multiplyDots "..." "..."

let dcd dt du =
dot { let! tens = dt
let! units = du
return (10 * tens + units)
}

let result7= dcd "..." "....."

// In Clojure the monad gets the lift for free
// In F# we have to create it ourselves
// More info: http://bugsquash.blogspot.com/2010/12/notes-on-haskell-functors-and-f.html --
//

let liftDots_1 f a1 =
dot {
let! x1 = a1
return f x1
}

let liftDots_2 f a1 a2 =
dot {
let! x1 = a1
let! x2 = a2
return f x1 x2
}

let liftDots_4 f a1 a2 a3 a4 =
dot {
let! x1 = a1
let! x2 = a2
let! x3 = a3
let! x4 = a4
return f x1 x2 x3 x4
}

let substractDots = liftDots_2 (-)

let result7a= substractDots "....." ".."

let mean4 a b c d = (a+b+c+d)/4

let dmean4 = liftDots_4 mean4

let result7b= dmean4 "..." ".." "..." "...."

//
//complex number (inspection)
//

open System.Numerics

let c_0 = Complex.Zero
let c_1 = Complex.One
let c_i = Complex.ImaginaryOne

type complexBuilder()=
member b.Return(x:float) = new Complex(x,0.0)
member b.Bind((c:Complex),(f:float -> Complex)) =
if c.Imaginary = 0.0 then
f c.Real
else
failwithf "Imaginary"

let complex = new complexBuilder()

let addComplex c1 c2 =
complex { let! x = c1
let! y = c2
return x + y
}

let result8= addComplex c_1 c_1;;
let result9= addComplex c_1 c_i;; //System.Exception: Imaginary
let result10= addComplex c_i c_i;; //System.Exception: Imaginary

//null

type noNullBuilder()=
member b.Return(mv) = mv
member b.Bind(mv,f) = if (mv = null) then null else f mv

let nuNull = new noNullBuilder()

// int can not be null in .Net

let fragile (a:string) (b:string) (c:string) =
if (a= null||b=null||c=null)
then
"CRASH"
else
a + b + c

let result11 = fragile "a" "b" "c"
let result12 = fragile "a" null "c" //"CRASH"

let safeFragile (a:string) (b:string) (c:string) =
nuNull { let! x = a
let! y = b
let! z = c
return x + y + z
}

let result13 = safeFragile "a" "b" "c"
let result14 = safeFragile "a" null "c" //val result14 : string = null

//List
let l_a = [1;2;3]
let l_b = [4;5;6]

let addList = seq {for a in l_a do
for
b in l_b do
yield
a+b
}|> Seq.toList

let multList = seq {for a in l_a do
for
b in l_b do
yield
a*b
}|> Seq.toList

//helper for the demo
let flatten l =
let rec flatten' l result =
match l with
|[] -> result
|h::t -> flatten' t (h@result)
flatten' (l|>List.rev) []

let result15 = flatten [[1;2;3];[7;8;9]]

type listBuilder()=
member b.Return(v) = [v]
member b.Bind(mv,f) = mv |> List.map f |> flatten

let list = new listBuilder()

let addList' a b = list {
let! x = a
let! y = b
return x + y
}

let result16 = addList' l_a l_b

let multList' a b = list {
let! x = a
let! y = b
return x * y
}

let result17 = multList' l_a l_b

//distribution example see Expert F# of Don Syme page 239..244
//state http://fsharpcode.blogspot.com/2008/12/f-state-monad-type-state-state-state-of.html

Wednesday, June 22, 2011

LINQ to XML, when lazy is too lazy in F# (and C# )

 

Today a F# program did not work as expected. This is a small example I created:

let xml ="<a><b>1</b><b>2</b></a>"
let doc = XDocument.Parse(xml)

let getXElements_b (doc:XDocument) =
let els = doc.Root.Elements(XName.Get("b"))
els
//test
let result1 = doc |> getXElements_b |> Seq.toList
//val result1 : XElement list = [<b>1</b>; <b>2</b>]
//the expected result 

let proces (el:XElement) =
XElement(XName.Get("c")) |> el.ReplaceWith

doc |> getXElements_b |> Seq.iter proces

let result2 =  doc.ToString();;
//val result2 : string = "<a>
//  <c />
//  <b>2</b>
//</a>"
This is not the expected result. I expected:

val result2 : string = "<a>
<c />
<c />
</a>"

I can fix it by changing the getXElements_b function:


let getXElements_b (doc:XDocument) =
let els = doc.Root.Elements(XName.Get("b")) |> Seq.toList
els

With this adjustment everything works fine. It seems that I have to force the the computation.


This is a problem in C# too.

private void GetXml()
{
var xml = "<a><b>1</b><b>2</b></a>";
var doc = XDocument.Parse(xml);
var els = doc.Root.Elements(XName.Get("b"));

foreach (var el in els)
{
el.ReplaceWith(new XElement(XName.Get("c")));
}

txtResult.Text = doc.ToString();
}
produces:

<a>
  <c />
  <b>2</b>
</a>


When I step with the debuger through the code the foreach is only one time triggered.


With support of Google I found the following document:


http://msdn.microsoft.com/en-us/library/bb308960.aspx


lazyXML


You can learn something new everyday.


Interesting links:

The "Halloween Problem" for XML APIs:

http://blogs.msdn.com/b/mikechampion/archive/2006/07/20/672208.aspx

Query Composition using Functional Programming Techniques in C# 3.0:

http://blogs.msdn.com/b/ericwhite/archive/2006/10/04/fp-tutorial.aspx

Monday, June 20, 2011

Update an open XML word document in F#

 
I have created a small function in F# to update the content of a word document.
//reference to the package 
#r "WindowsBase"
//reference to the Xml and Linq 
#r "System.Xml"
#r "System.Xml.Linq"

open System
open System.IO
open System.IO.Packaging
open System.Xml
open System.Xml.Linq

//helper to create XName with a namespace
let xname str =
XName.Get(str, "http://schemas.openxmlformats.org/wordprocessingml/2006/main")

// the main function 
// changeDoc copies a word .docx document and updates the content by changing the xml that represents the content
let changeDoc oldPath newPath (updateDocument:XDocument -> XDocument) =
//update the package part
let updatePart (part:PackagePart) =
using (part.GetStream(FileMode.Open, FileAccess.Read)) (fun stream -> 
let xDocumentOut = stream |> XDocument.Load |> updateDocument
xDocumentOut.Save(part.GetStream(FileMode.Create, FileAccess.Write))
)

File.Copy(oldPath, newPath, true)
using (Package.Open(newPath, FileMode.Open, FileAccess.ReadWrite)) (fun package ->
let uri = new Uri("/word/document.xml", UriKind.Relative )

uri |> package.GetPart|> updatePart
)

// test function to update the document
// adds "_test" to every text  in the document.
let updateText (xDoc:XDocument) =
"t" |> xname  |> xDoc.Descendants |> Seq.iter (fun x -> x.Value <- x.Value + "_test")
xDoc

//test
changeDoc @"D:\Tmp\test.docx" @"D:\Tmp\test_copy.docx" updateText;;
Before "D:\Tmp\test.docx":
before
 
After "D:\Tmp\test_copy.docx":
after

Tuesday, May 31, 2011

Create in F# XDocument with XDeclaration and namespace

In this example I will create the following XML in F#:
<?xml version="1.0" encoding="utf-8"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
  <w:body>
    <w:p>
      <w:r>
        <w:t>This is a test</w:t>
      </w:r>
    </w:p>
  </w:body>
</w:document>
 
Transferring C#-code is not straightforward because the constructor of XDocument does not accept the following code: new  XDocument(new XDeclaration("1.0""utf-8""true"), new XElement("document"))

//First create some helpers:

let xnameNs str ns = XName.Get(str, ns)
let xname str =
    xnameNs str "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
 
let ns = XNamespace.Get("http://schemas.openxmlformats.org/wordprocessingml/2006/main")
 
let dec = new XDeclaration("1.0""utf-8""true")
 
let el =
    new XElement(xname "document",
        new XAttribute(XNamespace.Xmlns + "w", ns),
            new XElement(xname "body",
                new XElement(xname "p",
                    new XElement(xname "r",
                        new XElement(xname "t""This is a test")
                        ))))
 
//Add them together:
 
let document = 
    let doc =new XDocument(dec)
    doc.AddFirst(el)
    doc

//And test:
 
document.Save(@"D:\Tmp\test1.xml")

Tuesday, May 24, 2011

Create Open XML Word document in F#

I needed a word document. I created it with the Open XML SDK and F# and posted the snippet at fssnip.net.

1: //reference to the Open Office SDK
2: #r @"C:\Program Files (x86)\Open XML SDK\V2.0\lib\DocumentFormat.OpenXml.dll"
3: //reference to the package
4: #r "WindowsBase"
5:
6: open DocumentFormat.OpenXml
7: open DocumentFormat.OpenXml.Wordprocessing
8: open DocumentFormat.OpenXml.Packaging
9:
10: let testString = "This is a test"
11: let printXml text =
12: printfn "xml: %s" text
13:
14: let createBody (text:string) =
15: let text = new Text(text)
16: let run = new Run()
17: run.AppendChild(text) |> ignore
18: let para = new Paragraph()
19: para.AppendChild(run)|> ignore
20: let body = new Body()
21: body.AppendChild(para)|> ignore
22: body
23:
24: printXml (createBody testString).InnerXml
25:
26: let createDocument (text:string) =
27: let body = createBody text
28: let doc = new Document()
29: doc.AppendChild(body) |> ignore
30: doc
31:
32: printXml (createDocument testString).InnerXml
33:
34: let createWordprocessingDocument (filepath:string) text=
35: using (WordprocessingDocument.Create(filepath, WordprocessingDocumentType.Document)) (fun doc ->
36: let mainPart = doc.AddMainDocumentPart();
37: mainPart.Document <- createDocument text
38: )
39:
40: let result3 = createWordprocessingDocument @"D:\Tmp\test1.docx" testString
val testString : string

Full name: Snippet.testString

type: string
implements: System.IComparable
implements: System.ICloneable
implements: System.IConvertible
implements: System.IComparable
implements: seq
implements: System.Collections.IEnumerable
implements: System.IEquatable
val printXml : string -> unit

Full name: Snippet.printXml
val text : string

type: string
implements: System.IComparable
implements: System.ICloneable
implements: System.IConvertible
implements: System.IComparable
implements: seq
implements: System.Collections.IEnumerable
implements: System.IEquatable
val printfn : Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val createBody : string -> 'a

Full name: Snippet.createBody
Multiple items
val string : 'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------

type string = System.String

Full name: Microsoft.FSharp.Core.string

type: string
implements: System.IComparable
implements: System.ICloneable
implements: System.IConvertible
implements: System.IComparable
implements: seq
implements: System.Collections.IEnumerable
implements: System.IEquatable
val text : 'a
namespace Microsoft.FSharp.Text
val run : 'a
val ignore : 'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
val para : 'a
val body : 'a
val createDocument : string -> 'a

Full name: Snippet.createDocument
val doc : 'a
val createWordprocessingDocument : string -> 'a -> 'b

Full name: Snippet.createWordprocessingDocument
val filepath : string

type: string
implements: System.IComparable
implements: System.ICloneable
implements: System.IConvertible
implements: System.IComparable
implements: seq
implements: System.Collections.IEnumerable
implements: System.IEquatable
val using : 'T -> ('T -> 'U) -> 'U (requires 'T :> System.IDisposable)

Full name: Microsoft.FSharp.Core.Operators.using
val doc : 'a (requires 'a :> System.IDisposable)

type: 'a
implements: System.IDisposable
val mainPart : 'a
val result3 : 'a

Full name: Snippet.result3

It is a direct transformation of the C# code from the help file of the Open XML SDK:

public static void CreateWordprocessingDocument(string filepath)
{
    // Create a document by supplying the filepath. 
    using (WordprocessingDocument wordDocument =
        WordprocessingDocument.Create(filepath, WordprocessingDocumentType.Document))
    {
        // Add a main document part. 
        MainDocumentPart mainPart = wordDocument.AddMainDocumentPart();
 
        // Create the document structure and add some text.
        mainPart.Document = new Document();
        Body body = mainPart.Document.AppendChild(new Body());
        Paragraph para = body.AppendChild(new Paragraph());
        Run run = para.AppendChild(new Run());
        run.AppendChild(new Text("Create text in body - CreateWordprocessingDocument"));
    }
}

Wednesday, February 6, 2008

F# union types in C#

An other name for union types is discriminated unions.
I was interested what a union type looks and behaves in C#.
I build small demo applcation:
private void nudTest_ValueChanged(object sender, EventArgs e)
{
int x = Convert.ToInt32(nudTest.Value);

if(PsA.resultOfVote(x).IsYes())
{
lblResult.Text = "Yes";
}

if(PsA.resultOfVote(x).IsNo())
{
lblResult.Text = "No";
}

if(PsA.resultOfVote(x).IsMaybe())
{
lblResult.Text = PsA.resultOfVote(x).Maybe1.ToString();
}
}
image
image
image
The object created by F# looked like this:
image
I called the dll PsA.

Total Pageviews