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.
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.
Thank you for the advice :)
I'm just exploring the limits of the language so is all fun for now ;)
Cheers
I'm just exploring the limits of the language so is all fun for now ;)
Cheers
Since I saw your blog
[link:fsharpcode.blogspot.com]
I just wanted to pour more cold water on
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. :)
[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. :)
Since I saw your blog
[link:fsharpcode.blogspot.com]
I just wanted to pour more cold water onI 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.
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
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
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:
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.
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.
- This is extremely ugly (to my eyes, at least), and probably goes against the "spirit" of F#
- 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).
Topic tags
- f# × 3660
- compiler × 263
- functional × 199
- c# × 119
- websharper × 114
- classes × 96
- web × 94
- book × 84
- .net × 82
- async × 72
- parallel × 43
- server × 43
- parsing × 41
- testing × 41
- asynchronous × 30
- monad × 28
- ocaml × 26
- tutorial × 26
- haskell × 25
- workflows × 22
- html × 21
- linq × 21
- introduction × 19
- silverlight × 19
- wpf × 19
- fpish × 18
- collections × 14
- pipeline × 14
- templates × 12
- monads × 11
- opinion × 10
- reactive × 10
- plugin × 9
- scheme × 9
- sitelets × 9
- solid × 9
- basics × 8
- concurrent × 8
- deployment × 8
- how-to × 8
- python × 8
- complexity × 7
- javascript × 6
- jquery × 6
- lisp × 6
- real-world × 6
- workshop × 6
- xaml × 6
- conference × 5
- dsl × 5
- java × 5
- metaprogramming × 5
- ml × 5
- scala × 5
- visual studio × 5
- formlets × 4
- fsi × 4
- lift × 4
- sql × 4
- teaching × 4
- alt.net × 3
- aml × 3
- enhancement × 3
- list × 3
- reflection × 3
- blog × 2
- compilation × 2
- computation expressions × 2
- corporate × 2
- courses × 2
- cufp × 2
- enterprise × 2
- entity framework × 2
- erlang × 2
- events × 2
- f# interactive × 2
- fsc × 2
- google maps × 2
- html5 × 2
- http × 2
- interactive × 2
- interface × 2
- iphone × 2
- iteratee × 2
- jobs × 2
- keynote × 2
- mvc × 2
- numeric × 2
- obfuscation × 2
- oop × 2
- packaging × 2
- pattern matching × 2
- pipelines × 2
- rx × 2
- script × 2
- seq × 2
- sockets × 2
- stm × 2
- tcp × 2
- trie × 2
- type × 2
- type provider × 2
- xna × 2
- zh × 2
- .net interop × 1
- 2012 × 1
- abstract class × 1
- accumulator × 1
- active pattern × 1
- addin × 1
- agents × 1
- agile × 1
- android × 1
- anonymous object × 1
- appcelerator × 1
- architecture × 1
- array × 1
- arrays × 1
- asp.net 4.5 × 1
- asp.net mvc × 1
- asp.net mvc 4 × 1
- asp.net web api × 1
- aspnet × 1
- ast × 1
- b-tree × 1
- bistro × 1
- bug × 1
- camtasia studio × 1
- canvas × 1
- class × 1
- client × 1
- clojure × 1
- closures × 1
- cloud × 1
- cms × 1
- coding diacritics × 1
- color highlighting × 1
- combinator × 1
- confirm × 1
- constructor × 1
- continuation-passing style × 1
- coords × 1
- coursera × 1
- csla × 1
- css × 1
- data × 1
- database × 1
- declarative × 1
- delete × 1
- dhtmlx × 1
- discriminated union × 1
- distance × 1
- docs × 1
- documentation × 1
- dol × 1
- domain × 1
- du × 1
- duf-101 × 1
- eclipse × 1
- edsl × 1
- em algorithm × 1
- emacs × 1
- emotion × 1
- error × 1
- etw × 1
- euclidean × 1
- event × 1
- example × 1
- ext js × 1
- extension methods × 1
- extra × 1
- facet pattern × 1
- fantomas × 1
- fear × 1
- float × 1
- fp × 1
- frank × 1
- fsdoc × 1
- fsharp.core × 1
- fsharp.powerpack × 1
- fsharpx × 1
- function × 1
- functional style × 1
- gc × 1
- generic × 1
- geometry × 1
- getlastwin32error × 1
- google × 1
- group × 1
- hash × 1
- history × 1
- hosting × 1
- httpcontext × 1
- https × 1
- hubfs × 1
- ie 8 × 1
- if-doc × 1
- inheritance × 1
- installer × 1
- interpreter × 1
- io × 1
- ios × 1
- ipad × 1
- kendo × 1
- learning × 1
- licensing × 1
- macro × 1
- macros × 1
- maps × 1
- markup × 1
- marshal × 1
- math × 1
- metro style × 1
- micro orm × 1
- minimum-requirements × 1
- multidimensional × 1
- multithreading × 1
- mysql × 1
- mysqlclient × 1
- nancy × 1
- nested × 1
- nested loops × 1
- node × 1
- object relation mapper × 1
- object-oriented × 1
- offline × 1
- option × 1
- orm × 1
- osx × 1
- owin × 1
- paper × 1
- parameter × 1
- performance × 1
- persistent data structure × 1
- phonegap × 1
- pola × 1
- powerpack × 1
- prefix tree × 1
- principle of least authority × 1
- programming × 1
- projekt_feladat × 1
- protected × 1
- provider × 1
- ptvs × 1
- quant × 1
- quotations × 1
- range × 1
- raphael × 1
- razor × 1
- rc × 1
- real-time × 1
- reference × 1
- restful × 1
- round table × 1
- runtime × 1
- scriptcs × 1
- scripting × 1
- service × 1
- session-state × 1
- sitelet × 1
- stickynotes × 1
- stress × 1
- strong name × 1
- structures × 1
- tdd × 1
- template × 1
- tracing × 1
- tsunamiide × 1
- type inference × 1
- type providers × 1
- upload × 1
- vb × 1
- vb.net × 1
- vector × 1
- visual f# × 1
- visual studio 11 × 1
- visual studio shell × 1
- visualstudio × 1
- web api × 1
- webapi × 1
- windows 8 × 1
- windows-phone × 1
- winrt × 1
- xml × 1
|
Copyright (c) 2011-2012 IntelliFactory. All rights reserved. Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us |
Built with WebSharper |
I would like this StateT to work on any monad. How do I do that? Statically resolved typed parameters ??
type StateT<'a, 'b, 'state> = StateT of ('state -> Parser<'a * 'state, 'b>) type StateTBuilder (p:ParserMonad) = // a -> m a member this.Return a = StateT (fun s -> p.Return(a, s)) // m a -> (a -> m b) -> m b member this.Bind (m, f) = StateT (fun s -> p { let! (v, s') = let (StateT f) = m in f s let (StateT f') = f v return! f' s' }) member this.Get = StateT (fun s -> p.Return(s, s)) member this.Put s = StateT (fun _ -> p.Return((), s)) let statefulParser = StateTBuilder(parser) let lift c = StateT (fun s -> parser.Bind (c, (fun x -> parser.Return (x, s))))