My advice is to give up now. :) Monad Transformers on .NET seem to really require first-class representation of "forall M. forall T. M<T> with Return/Bind/etc", and .NET doesn't support that.

You might be able to get pretty far with statically resolved type parameters, but I think you'll still fall down at the edge, and you'll waste lots of time exploring the edges and being frustrated at the cool stuff that's "just out of reach". That's my experience, anyway.

By on 5/3/2010 3:24 PM ()

Thank you for the advice :)

I'm just exploring the limits of the language so is all fun for now ;)

Cheers

By on 5/3/2010 3:35 PM ()

Since I saw your blog

[link:fsharpcode.blogspot.com]

I just wanted to pour more cold water on

I was told that with the current version of F# is almost impossible

and say "I think this will never be possible in any .NET language". That is probably too strong, but I think it's closer to being true than your words. :)

By on 5/3/2010 7:13 PM ()

Since I saw your blog

[link:fsharpcode.blogspot.com]

I just wanted to pour more cold water on

I was told that with the current version of F# is almost impossible

and say "I think this will never be possible in any .NET language". That is probably too strong, but I think it's closer to being true than your words. :)

On Scala days it was announced that they are working on a new Scala.NET compiler backed by MS, so that would make it possible since it's got higher kinded-types.

By on 5/4/2010 3:17 PM ()

I've updated the blog post. Thank you

Is it really that bad ? Is there anyone in Microsoft looking at this at the moment ? Any research project going on at MSR on how to fix this ?

Cheers,
Edmondo

By on 5/4/2010 4:50 AM ()

I'm not quite as pessimistic as Brian (though obviously he's privy to more authoritative information than I am). As it is, this almost works:

1
2
3
4
5
6
7
8
9
10
type StateT<'s,'m> = StateT of ('s -> 'm)


let inline returnS m a = StateT (fun s -> (^m : (member Return : ^a -> ^b) (m, (a,s))))
let inline bindS m v f s = StateT (fun s -> (^m : (member Bind : ^a -> ^b -> ^c) (m, v s, (fun (v,s') -> f v s'))))


type StateTBuilder< ^m>(m:^m) =
  member inline x.Return v = returnS m v
  member inline x.Bind(mv,f) = bindS m mv f

The main issue is that F# attempts to resolve the Bind and Return methods of type ^m in the declaration of type StateTBuilder, rather than where the StateTBuilder methods requiring those static constraints are used. Conceptually, at least, it would not be a dramatic shift for F#'s behavior to be changed in this regard for types which are parametrized by statically resolved type variables, though whether it would be a desirable change is of course debatable. In the meantime, if you specify a specific monad type in place of ^m in the definition of StateTBuilder, you should be able to create a StateTBuilder specific to that monad.

There are a few other issues as well.

  1. This is extremely ugly (to my eyes, at least), and probably goes against the "spirit" of F#
  2. You lose some of expressiveness of Haskell, since this code would allow StateTBuilder's to wrap types where Bind and Return aren't constrained to have correct monadic interpretations (e.g. ^m's Bind could have a non-generic type).
By on 5/4/2010 8:50 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper