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);
}
}
Related
F# does not (currently) support type-classes. However, F# does support the OOP aspects of C#.
I was wondering, what is lost doing this approach compared to true type-classes?
// A concrete type
type Foo =
{
Foo : int
}
// "Trait" for things that can be shown
type IShowable =
abstract member Show : unit -> string
module Showable =
let show (showable : IShowable) =
showable.Show()
// "Witness" of IShowable for Foo
module Foo =
let asShowable (foo : Foo) =
{
new IShowable with
member this.Show() = string foo.Foo
}
// Slightly awkward usage
{ Foo = 123 }
|> Foo.asShowable
|> Showable.show
|> printfn "%s"
Your suggestion works for simple typeclasses that operate on a single value of a type, like Show. However, what happens when you need a typeclass that isn't so object-oriented? For example, when we want to add two numbers, neither one corresponds to OO's this object:
// not real F#
typeclass Numeric<'a> = // e.g. Numeric<int> or Numeric<float>
abstract member (+) : 'a -> 'a -> 'a // e.g. 2 + 3 = 5 or 2.0 + 3.0 = 5.0
...
Also, keep in mind that many useful typeclasses require higher-kinded types. For example, consider the monad typeclass, which would look something like this:
// not real F#
typeclass Monad<'m<_>> = // e.g. Monad<Option<_>> or Monad<Async<_>>
abstract member Return<'a> : 'a -> 'm<'a>
abstract member Bind<'a, 'b> : 'm<'a> -> ('a -> 'm<'b>) -> 'm<'b>
There's no good way to do this with .NET interfaces.
Higher-kinded type classes are indeed impossible to model with interfaces, but that's just because F# does not support higher-kindedness, not because of type classes themselves.
The deeper thing to note is that your encoding isn't actually correct. Sure, if you just need to call show directly, you can do asShowable like that, but that's just the simplest case. Imagine you needed to pass the value to another function that wanted to show it later? And then imagine it was a list of values, not a single one:
let needsToShow (showable: IShowable) (xs: 'a list) =
xs |> List.iter (fun x -> ??? how do I show `x` ???)
No, this wouldn't do of course. The key is that Show should be a function 'a -> string, not unit -> string. And this means that IShowable itself should be generic:
// Haskell: class Showable a where show :: a -> String
type IShowable<'a> with
abstract member Show : 'a -> string
// Haskell: instance Showable Foo where show (Foo i) = show i
module Foo =
let showable = { new IShowable<Foo> with member _.Show foo = string foo.Foo }
// Haskell: needsToShow :: Show a => [a] -> IO ()
let needsToShow (showable: IShowable<'a>) (xs: 'a list) =
xs |> List.iter (fun x -> printfn "%s" (showable.Show x))
// Haskell: needsToShow [Foo 1, Foo 42]
needsToShow Foo.showable [ { Foo: 1 }; { Foo: 42 } ]
And this is, essentially, what type classes are: they're indeed merely dictionaries of functions that are passed everywhere as extra parameters. Every type has such dictionary either available right away (like Foo above) or constructable from other such dictionaries, e.g.:
type Bar<'a> = Bar of 'a
// Haskell: instance Show a => Show (Bar a) where show (Bar a) = "Bar: " <> show a
module Bar =
let showable (showA: IShowable<'a>) =
{ new IShowable<Bar<'a>> with member _.Show (Bar a) = "Bar: " + showA.Show a }
This is completely equivalent to type classes. And in fact, this is exactly how they're implemented in languages like Haskell or PureScript in the first place: like dictionaries of functions being passed as extra parameters. It's not a coincidence that constraints on function type signatures even kinda look like parameters - just with a fat arrow instead of a thin one.
The only real difference is that in F# you have to do that yourself, while in Haskell the compiler figures out all the instances and passes them for you.
And this difference turns out to be kind of important in practice. I mean, sure, for such a simple example as Show for the immediate parameter, you can just pass the damn instance yourself. And even if it's more complicated, I guess you could suck it up and pass a dozen extra parameters.
But where this gets really inconvenient is operators. Operators are functions too, but with operators there is nowhere to stick an extra parameter (or dozen). Check this out:
x = getY >>= \y -> getZ y <&> \z -> y + 42 > z
Here I used four operators from four different classes:
>>= comes from Monad
<&> from Functor
+ from Num
> from Ord
An equivalent in F# with passing instances manually might look something like:
let x =
bind Foo.monad getY <| fun y ->
map Bar.functor (getZ y) <| fun z ->
gt Int.ord (add Int.num y 42) z
Having to do that everywhere is quite unreasonable, you have to agree.
And this is why many F# operators either use SRTPs (e.g. +) or rely on "known" interfaces (e.g. <) - all so you don't have to pass instances manually.
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.
What's the most idiomatic way in F# to deal with the following. Suppose I have a property I want a type to satisfy that doesn't make sense on an instance level, but ideally I would like to have some pattern matching available against it?
To make this more concrete, I have defined an interface representing the concept of a ring (in the abstract algebra sense). Would I go for:
1.
// Misses a few required operations for now
type IRing1<'a when 'a: equality> =
abstract member Zero: 'a with get
abstract member Addition: ('a*'a -> 'a) with get
and let's assume I'm using it like this:
type Integer =
| Int of System.Numerics.BigInteger
static member Zero with get() = Int 0I
static member (+) (Int a, Int b) = Int (a+b)
static member AsRing
with get() =
{ new IRing1<_> with
member __.Zero = Integer.Zero
member __.Addition = Integer.(+) }
which allows me to write things like:
let ring = Integer.AsRing
which then lets me to nicely use the unit tests I've written for verifying the properties of a ring. However, I can't pattern match on this.
2.
type IRing2<'a when 'a: equality> =
abstract member Zero: 'a with get
abstract member Addition: ('a*'a -> 'a) with get
type Integer =
| Int of System.Numerics.BigInteger
static member Zero with get() = Int 0I
static member (+) (Int a, Int b) = Int (a+b)
interface IRing2<Integer> with
member __.Zero = Integer.Zero
member __.Addition with get() = Integer.(+)
which now I can pattern match, but it also means that I can write nonsense such as
let ring = (Int 3) :> IRing2<_>
3.
I could use an additional level of indirection and basically define
type IConvertibleToRing<'a when 'a: equality>
abstract member UnderlyingTypeAsRing : IRing3<'a> with get
and then basically construct the IRing3<_> in the same way as under #1.
This would let me write:
let ring = ((Int 3) :> IConvertibleToRing).UnderlyingTypeAsRing
which is verbose but at least what I'm writing doesn't read as nonsense anymore. However, next to the verbosity, the additional level of complexity gained doesn't really "feel" justifiable here.
4.
I haven't fully thought this one through yet, but I could just have an Integer type without implementing any interfaces and then a module named Integer, having let bound values for the Ring interfaces. I suppose I could then use reflection in a helper function that creates any IRing implementation for any type where there is also a module with the same name (but with a module suffix in it's compiled name) available? This would combine the benefits of #1 and #2 I guess, but I'm not sure whether it's possible and/or too contrived?
Just for background: Just for the heck of it, I'm trying to implement my own mini Computer Algebra System (like e.g. Mathematica or Maple) in F# and I figured that I would come across enough algebraic structures to start introducing interfaces such as IRing for unit testing as well as (potentially) later for dealing with general operations on such algebraic structures.
I realize part of what is or isn't possible here has more to do with restrictions on how things can be done in .NET rather than F#. If my intention is clear enough, I'd be curious to here in comments how other functional languages work around this kind of design questions.
Regarding your question about how can you implement Rings in other functional languages, in Haskell you will typically define a Type Class Ring with all Ring operations.
In F# there are no Type Classes, however you can get closer using inline and overloading:
module Ring =
type Zero = Zero with
static member ($) (Zero, a:int) = 0
static member ($) (Zero, a:bigint) = 0I
// more overloads
type Add = Add with
static member ($) (Add, a:int ) = fun (b:int ) -> a + b
static member ($) (Add, a:bigint) = fun (b:bigint) -> a + b
// more overloads
type Multiply = Multiply with
static member ($) (Multiply, a:int ) = fun (b:int ) -> a * b
static member ($) (Multiply, a:bigint) = fun (b:bigint) -> a * b
// more overloads
let inline zero() :'t = Zero $ Unchecked.defaultof<'t>
let inline (<+>) (a:'t) (b:'t) :'t= (Add $ a) b
let inline (<*>) (a:'t) (b:'t) :'t= (Multiply $ a) b
// Usage
open Ring
let z : int = zero()
let z': bigint = zero()
let s = 1 <+> 2
let s' = 1I <+> 2I
let m = 2 <*> 3
let m' = 2I <*> 3I
type MyCustomNumber = CN of int with
static member ($) (Ring.Zero, a:MyCustomNumber) = CN 0
static member ($) (Ring.Add, (CN a)) = fun (CN b) -> CN (a + b)
static member ($) (Ring.Multiply, (CN a)) = fun (CN b) -> CN (a * b)
let z'' : MyCustomNumber = zero()
let s'' = CN 1 <+> CN 2
If you want to scale up with this approach you can have a look at FsControl which already defines Monoid with Zero (Mempty) and Add (Mappend). You can submit a pull request for Ring.
Now to be practical if you are planning to use all this only with numbers why not use GenericNumbers in F#, (+) and (*) are already generic then you have LanguagePrimitives.GenericZero and LanguagePrimitives.GenericOne.
I'm trying to build a log4net style interface in an F# assembly. The key attribute is exposing a static method that returns an instance of an object. log4net makes use of C# delegates to accomplish the task, e.g. with LogManager.GetLogger("log123"). Delegates, from my understanding, are less favored than functions-as-first-class for inward-facing F# libraries.
The simplified code below accomplishes the objective, but I am uncomfortable with the use of an F# reference cell to hold a map of instantiated objects. I am interested in feedback on whether my discomfort is warranted.
namespace Test
[<Interface>]
type IMyIface =
abstract member Addi : int -> int
[<Sealed>]
type TheMainObject internal (x:int) =
let mutable sum = x
interface IMyIface with
member this.Addi(y:int) = sum <- sum + y; sum
module internal Wrapr =
let mymap = ref Map.empty
let mgr s =
let m = !mymap
if Map.containsKey s m then m.[s]
else
let x = new TheMainObject(0)
mymap := m.Add(s, x)
x
[<Sealed>]
type Mgr() =
static member Get(n:string) =
Wrapr.mgr n :> IMyIface
Program.fs calls the library above as follows:
open Test
let a = Mgr.Get("hello")
printfn "%d" (a.Addi(1))
let c = Mgr.Get("hello")
printfn "%d, %A" (c.Addi(3)) (a = c) //prints 4, true
Thanks in advance for comments.
It's OK to use a reference cell internally to hold a mutable value. You could also use a .Net Dictionary instead of a map. This is the approach I took while building a Mini IoC Container. If you expect the function accessing the reference cell to be called from multiple threads then you should probably use a lock or other thread synchronization.
There are a number of ways of exposing the Get method. The static member approach you have taken is useful if you expect to overload the method. In which case you may consider using static let for static locals over a separate module:
type [<Sealed>] Mgr() =
static let sync = obj()
static let lookup = Dictionary()
static let obtain name =
match lookup.TryGetValue(name) with
| true, x -> x
| false,_ ->
let x = TheMainObject(0)
lookup.Add(name,x)
x
static member Get(name:string) =
lock sync (fun () -> obtain name :> IMyIface)
If you do not expect to overload the Get function then you could just use a module:
module Mgr =
let private lookup = ref Map.empty
let private obtain name =
match (!lookup).TryFind name with
| Some(x) -> x
| None ->
let x = TheMainObject(0)
lookup := (!lookup).Add(name,x)
x
let Get name = obtain name :> IMyIface
I am trying to emulate a system of type classes in F#; I would like to create pair printer which automatically instantiates the right series of calls to the printing functions. My latest try, which is pasted here, fails miserably since F# cannot identify the right overload and gives up immediately:
type PrintableInt(x:int) =
member this.Print() = printfn "%d" x
let (!) x = PrintableInt(x)
type Printer() =
static member inline Print< ^a when ^a : (member Print : Unit -> Unit)>(x : ^a) =
(^a : (member Print : Unit -> Unit) x)
static member inline Print((x,y) : 'a * 'b) =
Printer.Print(x)
Printer.Print(y)
let x = (!1,!2),(!3,!4)
Printer.Print(x)
Is there any way to do so? I am doing this in the context of game development, so I cannot afford the runtime overhead of reflection, retyping and dynamic casting: either I do this statically through inlining or I don't do it at all :(
What you're trying to do is possible.
You can emulate typeclasses in F#, as Tomas said maybe is not as idiomatic as in Haskell. I think in your example you are mixing typeclasses with duck-typing, if you want to go for the typeclasses approach don't use members, use functions and static members instead.
So your code could be something like this:
type Print = Print with
static member ($) (_Printable:Print, x:string) = printfn "%s" x
static member ($) (_Printable:Print, x:int ) = printfn "%d" x
// more overloads for existing types
let inline print p = Print $ p
type Print with
static member inline ($) (_Printable:Print, (a,b) ) = print a; print b
print 5
print ((10,"hi"))
print (("hello",20), (2,"world"))
// A wrapper for Int (from your sample code)
type PrintableInt = PrintableInt of int with
static member ($) (_Printable:Print, (PrintableInt (x:int))) = printfn "%d" x
let (!) x = PrintableInt(x)
let x = (!1,!2),(!3,!4)
print x
// Create a type
type Person = {fstName : string ; lstName : string } with
// Make it member of _Printable
static member ($) (_Printable:Print, p:Person) = printfn "%s, %s" p.lstName p.fstName
print {fstName = "John"; lstName = "Doe" }
print (1 ,{fstName = "John"; lstName = "Doe" })
Note: I used an operator to avoid writing the constraints by hand, but in this case is also possible to use a named static member.
More about this technique here.
What you're trying to do is not possible (edit: apparently, it can be done - but it might not be idiomatic F#), because the constraint language cannot capture the constraints you need for the second Print operation. Basically, there is no way to write recursive constraints saying that:
Let C be a constraint specifying that the type either provides Print or it is a two-element tuple where each element satisfies C.
F# does not support type-classes and so most of the attempts to emulate them will (probably) be limited in some way or will look very unnatural. In practice, instead of trying to emulate solutions that work in other languages, it is better to look for an idiomatic F# solution to the problem.
The pretty printing that you're using as a sample would be probably implemented using Reflection or by wrapping not just integers, but also tuples.