I was trying to get a better understanding of the Functional way of coding, and just wrote a small program to print back the factorial of a user-entered number:
open System
let fact n = let rec factiter init acc =
if init = 0 then acc
else factiter (init - 1) init*acc
factiter n 1
let dropStrArr (argv: string []) = ignore argv
let factComp = Console.ReadLine >> Int32.Parse >> fact >> Console.WriteLine >> fun () -> 0
[<EntryPoint>]
let main argv = (dropStrArr >> factComp) argv
This worked fine but then I thought main could be defined purely by composition and tried:
let main = dropStrArr >> factComp
which I thought would work, but although it compiles, it simply exits immediately upon running.
There are different types in the two scenarios:
unit -> int
when main is defined with its argument, versus
(unit -> int)
when using composition.
I'm probably missing about the type system, so my question is why can't main just be defined via composition here?
The short answer is that writing point-free style in F# has consequences.
Functions which are partially applied, get compiled to FSharpFunc and are subsequently called with Invoke.
To illustrate:
let mul a b = a + b
let mul2 = mul 2 //point-free
let mul2P a = mul 2 a //pointed
mul2P look something like you'd expect (in equivalent C#)
static int mul2P(int a) { return mul(2, a); }
while mul2 becomes
class mul2Impl : FSharpFunc<int, int>
{
public int a;
mul2Impl(int a) { this.a = a; }
public override int Invoke(int b)
{
return mul(this.a, b);
}
}
So when you write let main argv it becomes a simple static method which just calls the other two FSharpFunc with
factComp.Invoke(dropStrArr.Invoke(argv));
But when you compose it, main becomes an FSharpFunc and there's no more a static main method as is required.
Related
I'm trying to wrap my head around mon-, err, workflows in F# and while I think that I have a pretty solid understanding of the basic "Maybe" workflow, trying to implement a state workflow to generate random numbers has really got me stumped.
My non-completed attempt can be seen here:
let randomInt state =
let random = System.Random(state)
// Generate random number and a new state as well
random.Next(0,1000), random.Next()
type RandomWF (initState) =
member this.Bind(rnd,rest) =
let value, newState = rnd initState
// How to feed "newState" into "rest"??
value |> rest
member this.Return a = a // Should I maybe feed "initState" into the computation here?
RandomWF(0) {
let! a = randomInt
let! b = randomInt
let! c = randomInt
return [a; b; c]
} |> printfn "%A"
Edit: Actually got it to work! Not exactly sure how it works though, so if anyone wants to lay it out in a good answer, it's still up for grabs. Here's my working code:
type RandomWF (initState) =
member this.Bind(rnd,rest) =
fun state ->
let value, nextState = rnd state
rest value nextState
member this.Return a = fun _ -> a
member this.Run x = x initState
There are two things that make it harder to see what your workflow is doing:
You're using a function type for the type of your monad,
Your workflow not only builds up the computation, it also runs it.
I think it's clearer to follow once you see how it would look without those two impediments. Here's the workflow defined using a DU wrapper type:
type Random<'a> =
Comp of (int -> 'a * int)
let run init (Comp f) = f init
type Random<'a> with
member this.Run(state) = fst <| run state this
type RandomBuilder() =
member this.Bind(Comp m, f: 'a -> Random<_>) =
Comp <| fun state ->
let value, nextState = m state
let comp = f value
run nextState comp
member this.Return(a) = Comp (fun s -> a, s)
let random = RandomBuilder()
And here is how you use it:
let randomInt =
Comp <| fun state ->
let rnd = System.Random(state)
rnd.Next(0,1000), rnd.Next()
let rand =
random {
let! a = randomInt
let! b = randomInt
let! c = randomInt
return [a; b; c ]
}
rand.Run(0)
|> printfn "%A"
In this version you separately build up the computation (and store it inside the Random type), and then you run it passing in the initial state. Look at how types on the builder methods are inferred and compare them to what MSDN documentation describes.
Edit: Constructing a builder object once and using the binding as an alias of sorts is mostly convention, but it's well justified in that it makes sense for the builders to be stateless. I can see why having parameterized builders seems like a useful feature, but I can't honestly imagine a convincing use case for it.
The key selling point of monads is the separation of definition and execution of a computation.
In your case - what you want to be able to do is to take a representation of your computation and be able to run it with some state - perhaps 0, perhaps 42. You don't need to know the initial state to define a computation that will use it. By passing in the state to the builder, you end up blurring the line between definition and execution, and this simply makes the workflow less useful.
Compare that with async workflow - when you write an async block, you don't make the code run asynchronously. You only create an Async<'a> object representing a computation that will produce an object of 'a when you run it - but how you do it, is up to you. The builder doesn't need to know.
The next test fail. I call GetType directly to a function definition, and then I also call GetType within an inline function. The generated types are not equal.
namespace PocTests
open FsUnit
open NUnit.Framework
module Helpers =
let balance ing gas = ing - gas
[<TestFixture>]
type ``Reflected types`` ()=
[<Test>] member x.
``test type equality with inline use`` () =
let inline (=>) f = f.GetType().FullName, f in
let fullName, fval = (=>) Helpers.balance in
Helpers.balance.GetType().FullName |> should equal (fullName)
How could I get the same type in order to be "comparable".
When you use a function as a value, F# does not give you any guarantees that the two created objects will be the "same". Under the cover the compiler creates a new closure object for each instance, so you will actually get false as the result even when you try something like this:
balance.GetType().FullName = balance.GetType().FullName
This is the intended behavior - when you try comparing functions directly, the compiler will tell you that functions do not satisfy the equality constraint and cannot be compared:
> let balance ing gas = ing - gas;;
val balance : ing:int -> gas:int -> int
> balance = balance;;
error FS0001: The type '(int -> int -> int)' does not support the
'equality' constraint because it is a function type
This means that the best answer to your question is that what you're asking for cannot be done. I think that comparing function values is most likely not a good idea, but perhaps there is a better answer for your specific problem if you provide some more details why you want to do this.
If you really want to perform equality testing on function values, then probably the cleanest approach is to define an interface and test ordinary object equality:
type IFunction =
abstract Invoke : int * int -> int
let wrap f =
{ new IFunction with
member x.Invoke(a, b) = f a b }
Now you can wrap the balance function in an interface implementation that can be compared:
let balance ing gas = ing - gas
let f1 = wrap balance
let f2 = f1
let f3 = wrap balance
f1 = f2 // These two are the same object and are equal
f1 = f3 // These two are different instances and are not equal
every time you call Helpers.balance a new closure is created, so
Helpers.balance.GetType().FullName |> printfn "%A" //output: "Program+main#22-1"
Helpers.balance.GetType().FullName |> printfn "%A" //output: "Program+main#23-2"
with class like (decompiled from compiled exe in c#)
[Serializable]
internal class main#22-1 : OptimizedClosures.FSharpFunc<int, int, int>
{
internal main#22-1()
{
base..ctor();
}
public override int Invoke(int ing, int gas)
{
return Program.Helpers.balance(ing, gas);
}
}
I need to do some setup in a module that I wanted to accomplish by leveraging a do block. Strangely though, my do block never seems to get hit.
Even stranger, If I load the module code into fsi, it does get hit. Here is my example:
Main.fs
[<EntryPoint>]
let main args =
printfn "%b" TestNamespace.M.x
0
TestModule.fs
namespace TestNamespace
module M =
do
printfn "In do"
failwith "Error" // this is line 6
let x = true
When I run the compiled executable I get
>test.exe
true
Why didn't the exception get thrown? If I run the module in FSI by itself I get
In do
System.Exception: Error
at <StartupCode$FSI_0006>.$FSI_0006.main#() in C:\Projects\Personal2\Playground\fsscripts\fsscripts\TestModule.fs:line 6
Stopped due to error
So it got the exception.
I see that in the decompliation that the do initializers get rolled into a seperate class
namespace \u003CStartupCode\u0024fsscripts\u003E
{
internal static class \u0024Library1
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
[CompilerGenerated]
[DebuggerNonUserCode]
internal static int init\u0040;
static \u0024Library1()
{
ExtraTopLevelOperators.PrintFormatLine<Unit>((PrintfFormat<Unit, TextWriter, Unit, Unit>) new PrintfFormat<Unit, TextWriter, Unit, Unit, Unit>("In do"));
Operators.FailWith<Unit>("Error");
bool x = M.x;
}
}
}
VS the actual module code:
namespace TestNamespace
{
[CompilationMapping(SourceConstructFlags.Module)]
public static class M
{
public static bool x
{
[DebuggerNonUserCode] get
{
return true;
}
}
}
}
So how do I make sure the do block actually gets executed?
--
Edit, given the above example counts as a simple constant expression so won't produce an observable initialization, why does the following also not work?
[<EntryPoint>]
let main args =
printfn "%d" (TestNamespace.M.x id 1)
0
namespace TestNamespace
module M =
do
printfn "In do"
failwith "Error"
let x f a = f a
This prints out 1 no problem.
Edit, after having re-read Tomas's comments its because a function is considered a constant expression.
For a good explanation of the problem, see the answer to this previous SO question. The important bit says:
the static initializer for the file is executed on first access of a value that has observable initialization
Now, "observable initialization" is somewhat tricky idea, but simple constant initialization definitely does not have observable initialization - that's why the do block is not executed. You can trick the compiler into thinking that there is some imperative action, for example by adding do ():
module M =
do
printfn "In do"
failwith "Error" // this is line 6
let x = (do ()); true
You can get the behavior you want, while maintaining the same public interface, with a class:
type M private () =
static do
printfn "In do"
failwith "Error"
static member val x = true
Here is a clean way to do it.
First, note that if you wanted the initialization code to run every time the function is called, you would do this:
module M =
let init () =
printfn "In init"
let x f a =
init ()
printfn "In x"
f a
So, if you want it to be called just once (static initialization), you can simply remove the () from both places:
module M =
let init =
printfn "In init"
let x f a =
init
printfn "In x"
f a
The nice thing is that you have documented your design that the init code will be called first. If you have several separate blocks of initialization code, it is clear which dependency you are relying on (although the first initialization will execute all such blocks of course).
UPDATE
Here is a version, which works in a Release build too. Not quite so clean, but almost:
module Init =
open System.Runtime.CompilerServices
[<MethodImpl(MethodImplOptions.NoInlining)>]
let call init = init
module M =
let init =
printfn "In init"
let x f a =
Init.call init
printfn "In x"
f a
Note that init is still a unit value, so Init.call is a non-inlined function that does nothing at all. So there is the overhead of a function call to nothing.
An alternative, which also works but seems a little strange is this:
module M =
let mutable init =
printfn "In init"
let x f a =
init <- init
printfn "In x"
f a
Can anyone improve on this?
What would be an elegant way to implement the functionality of this nested class in F#?
private class Aliaser {
private int _count;
internal Aliaser() { }
internal string GetNextAlias() {
return "t" + (_count++).ToString();
}
}
This was my first attempt, but it feels like there should be a sexy one-liner for this:
let aliases = (Seq.initInfinite (sprintf "t%d")).GetEnumerator()
let getNextAlias() =
aliases.MoveNext() |> ignore
aliases.Current
The usual way of writing is to create a function with local state captured in a closure:
let getNextAlias =
let count = ref 0
(fun () ->
count := !count + 1;
sprintf "t%d" (!count))
The type of getNextAlias is simply unit -> string and when you call it repeatedly, it returns strings "t1", "t2", ... This relies on mutable state, but the mutable state is hidden from the user.
Regarding whether you can do this without mutable state - the simple answer is NO, because when you call a purely functional function with the same parameter twice, it must return the same result. Thus, you'd have to write something with the following structure:
let alias, state1 = getNextAlias state0
printf "first alias %s" alias
let alias, state2 = getNextAlias state1
printf "second alias %s" alias
// ...
As you can see, you'd need to keep some state and maintain it through the whole code. In F#, the standard way of dealing with this is to use mutable state. In Haskell, you could use State monad, which allows you to hide the passing of the state. Using the implementation from this question, you could write something like:
let getNextAlias = state {
let! n = getState
do! setState (n + 1)
return sprintf "t%d" n }
let program =
state {
let! alias1 = getNextAlias()
let! alias2 = getNextAlias()
// ...
}
execute progam 0 // execute with initial state
This is quite similar to other computations such as lazy or seq, actually - computations in the state { .. } block have some state and you can execute them by providing initial value of the state. However, unless you have good reasons for requiring purely functional solution, I'd prefer the first version for practical F# programming.
Here is the quick and dirty translation
type Aliaser () =
let mutable _count = 0
member x.GetNextAlias() =
let value = _count.ToString()
_count <- _count + 1
"t" + value
A more functional approach without state is to use continuations.
let createAliaser callWithValue =
let rec inner count =
let value = "t" + (count.ToString())
callWithValue value (fun () -> inner (count + 1))
inner 1
This is a declaration which will call the function callWithValue with both the value and the function to execute to repeat with the next value.
And here's an example using it
let main () =
let inner value (next : unit -> unit )=
printfn "Value: %s" value
let input = System.Console.ReadLine()
if input <> "quit" then next()
createAliaser inner
main()
I would use Seq.unfold : (('a -> ('b * 'a) option) -> 'a -> seq<'b>) to generate the aliases.
Implemented as:
let alias =
Seq.unfold (fun count -> Some(sprintf "t%i" count, count+1)) 0
I'm wondering what others have come up with for dealing with Nullable<'T> in F#. I want to use Nullable<'T> on data types so that serialization works properly (i.e., doesn't write out F# option type to XML). But, I don't want my code stuck dealing with the ugliness of dealing with Nullable<'T> directly. Any suggestions?
Is it better to use active patterns to match directly on Nullable, or just a converter to option and use Some/None matching?
Additionally, I'd love to hear ideas on dealing with nullable references in a nice manner too. If I use, say "string option", then I end up with the F# option type wrapping things. If I don't then I can't distinguish between truly optional strings and strings that shouldn't be null.
Any chance .NET 4 will take on an Option<'T> to help out? (If it's part of the BCL, then we might see better support for it...)
As active patterns as options plays nicely with pattern matching, but is seems by using active patterns (i.e. typeof and ??) your code will eat more ticks.
The base question is how you will deal with your nullable references?
In case your code is long chained computations it's nice to use monadic syntax:
type Maybe<'a> = (unit -> 'a option)
let succeed x : Maybe<'a> = fun () -> Some(x)
let fail : Maybe<'a> = fun () -> None
let run (a: Maybe<'a>) = a()
let bind p rest = match run p with None -> fail | Some r -> (rest r)
let delay f = fun () -> run (f ())
type MaybeBuilder() =
member this.Return(x) = succeed x
member this.Let(p,rest) = rest p
member this.Bind(p,rest) = bind p rest
member this.Delay(f) = delay f
let maybe = new MaybeBuilder()
let add (a:'a) (b:'a) =
maybe {
match TryGetNumericAssociation<'a>() with
| Some v -> return (v.Add(a,b))
| _ -> return! fail
}
let add3 (a:'a) (b:'a) (c:'a) =
maybe {
let! ab = add a b
let! abc = add ab c
return abc
}
> let r1 = add 1 2;;
val r1 : (unit -> int option)
> r1();;
val it : int option = Some 3
> let r2 = add "1" "2";;
val r2 : (unit -> string option)
> r2();;
val it : string option = None
> let r3 = add3 "one" "two" "three";;
val r3 : (unit -> string option)
> r3();;
val it : string option = None