Hello,
Welcome to the community! No need to be nervous about posting here we try to be friendly and welcoming.
I think I understand your code and it seems correct to me. I understand that the code is just for fun, but I'm strugging to see why you'd want to do this in F#, since F# already has the arrow notation build in. It feels like your adding an extra layer were it is needed, or is there another perpose I'm missing? I guess if it was compiled to a library this could be used to provide currying in languages that didn't support it, ie C#/VB.NET?
Cheers,
Rob
I did not realize that it had already been implemented in F#. So what is the F# notation for arrow as I have missed it somehow? If it isn't to much trouble what should I search for to see an example of this?
Hi there,
Robert, "arrow" in this context is referring to the Haskell notion of "arrow", a very nice and powerful generalization of monads.
thanks
don
Apologies for the confusion, I am unfamilar with haskel. I thought arrow was refering to -> from a function type signature. I did try and google for arrows, but you find lots of information about the Robin Hood kind. If you had any links to information about arrows, please feel free to share them.
Cheers,
Rob
Rob, one Arrows tutorial that i recommend is Understanding Arrows from the Haskell wikibook. The first part of the tutorial doesn't use much Haskell syntax. The Arrows concept is interesting but i haven't seen it used much. One of Haskell's XML libraries uses arrows, but it is imo too complex and libraries like that one are getting "light" alternatives that are much easier to use.
A nice, practical paper about Arrows and functional reactive programming is at [link:www.haskell.org]
I'm interested in your progress, thedwalker. Do let us know what you're up to. :)
bye
Kurt
I'll try. I've hit a bit of a snag with implementing the loop, left, right, and ||| combinators. The latter is probably just that I haven't totally grasped how it should work. Or maybe I'm overthinking which wouldn't be a surprise for me.
One thing that struck me as odd was I couldn't seem to get the some of operator to work as static members. I receive a type constraint mismatch error when I try to define ( >>> ) within the Arrow type. ( &&& ) gives infers a type signature of:
Arrow<'a,'b> -> Arrow<'a,'b> -> Arrow<'a,('b*'b)>
However when I defined them in a manner similar to C# extension methods everything was fine except ( >>> ) gives a type constraint mismatch in the definition of the 'second' function
or it'll act as if I did not overload the operator.
Hi there
You'll should probably use a different operator name, ">>>" and "&&&" conflict with the default operators used for overloaded bitwise integer manipulations. Normally this doesn't matter but the default definition for ">>>" restricts the signature more than you need.
Knid regards
don
I can see how that can affect things, but interestingly like I said it only happens when I make it a static extension of the Arrow type. Even if I change the name of the functions as ( >>> ) and ( &&& ) was originally named combine and par respectively because the tooltip type signatures don't seem to work for me on user-defined operator.
On a slight tangent I did find a rather convoluted example that transformed intergers into their roman numeral representations using. Here it is:
let unfold f x =
let rec loop x acc =
match f x with
| None -> List.rev acc
| Some(a, x') -> loop x' (a::acc)
loop x []
let numerals = [("M", 1000); ("CM", 900); ("D", 500); ("CD", 400);
("C", 100); ("XC", 90); ("L", 50); ("XL", 40);
("X", 10); ("IX", 9); ("V", 5); ("IV", 4);
("I", 1)]
let next n =
match n with
| 0 -> None
| _ -> numerals |> List.filter (fun x-> let _,s = x in s <= n) |> List.hd |> (second (arr (fun x-> n - x))).run |> Some
let romanize x = List.reduce_left (fun (a: string) (i:string) ->a ^ i )(unfold next x)
It's been almost ten days since my last post on implementing the arrows and some of it common combinators. That's partially because of work and because I had hit a bit of a bump in the road. But the bump has been overcome so I have had a chance to implement the left, right, |||, and the +++ combinators. Submitted for your perusal, the code:
type either<'a, 'b> =
| Left of 'a
| Right of 'b
let ( |.| ) (f: Arrow<'a, 'c>) (g:Arrow<'b, 'c>) =
arr (fun x -> match x with
| Left a -> f.run a
| Right b -> g.run b
)
let left (f: Arrow<'a,'b>) =
arr (
fun x -> match x with
| Left a -> Left (f.run a)
| Right a -> Right a
)
let right (f: Arrow<'a, 'b>) =
let mirror = fun x -> match x with
| Left a -> Right a
| Right a -> Left a
(arr mirror) >.> left f >.> (arr mirror)
let ( +.+ ) (f: Arrow<'a,'b>) (g: Arrow<'c,'d>) = (left f) >.> (right g)
As you can see I took Don' suggestion and renamed the combinator that conflict with existing operator. It works fine although now the definitions look like emoticon.
All that is really left now is loop. But that will be a beast to figure out. As I can't make heads or tails of the definitions I've seen for it. For instance, the Haskell definiton is:
loop :: arr (a, c) (b, c) -> arr a b
loop f a = b
where (b, c) = f (a, c)
From this Haskell, I surmised that it would look something like this in F#:
val loop : Arrow<'a*'c, 'b*'c> -> Arrow<'a, 'b>
let loop (f:Arrow<'a*'c, 'b*'c> =
arr (
fun a ->
let mutable st = init
let b,c = f.run (a, st) in st <- c
b)
But this for some reason doesn't sit right with me. It should take the component c and feed it back in the the function f contains. Am I missing something?
What's the definition of >.>? Looks like it was missing?
For "Loop" you are writing a very funky and general tie-the-knot combinator. Because F# is strict you will need to insert some explicit laziness, and the operator will only make sense for lazy "c" types, i.e. types where you can provably embed/delay computations. You can do this in at least three ways
<UL><li>pass in a "delay" function that embeds "unit -> c" into "c"</LI><li>change the type of "loop" so that it includes lazy<c> on the input side.</LI><li>change the type of "loop" so that it includes "unit -> c" on the input side.</LI></UL> For example, I quite like this approach: let loop delay (f:Arrow<_,_>) = arr (fun b -> let rec p = f.run (b,delay (fun () -> snd p)) fst p) You then instantiate "delay" for each looping type, e.g. to "Seq.delay": let loopWithSequenceFeedback f = loop Seq.delay f Here's the alternative that inserts "lazy" into the type: let loop2 delay (f:Arrow<_,_>) = arr (fun b -> let rec p = f.run (b,lazy (snd p)) fst p) and the usage site would still need to propagate the feedback laziness through the feedback type. Here's another possibility which is effectively the same thing and is similar to what you had but with a "lazy" delay let loop3 (f:Arrow<_,_>) = arr (fun b -> let p = ref None p := Some (f.run (b,lazy (snd (!p).Value))) fst (!p).Value) Anyway, that's my shot at it today don
Thanks Don! That's where I couldn't quite get my brain to go. I forgot that since the most of the material written about Hughes' Arrows are from a Haskell point of view, that sooner or later Haskell's laziness would be taken for granted in the definition of a combinator.
To clarify the operators that mysteriously appeared in my last post. I renamed them from >>>, &&&, |||, ***, and +++ to >.>, &.&, |.|, *.*, and +.+ respectively. Sorry for the lack of explanation on that.
Topic tags
- f# × 3705
- websharper × 1897
- compiler × 286
- functional × 201
- ui next × 139
- c# × 121
- classes × 97
- web × 97
- .net × 84
- book × 84
- async × 76
- ui.next × 67
- bug × 54
- core × 49
- website × 49
- server × 45
- parallel × 43
- ui × 43
- enhancement × 41
- parsing × 41
- testing × 41
- trywebsharper × 41
- typescript × 37
- html × 35
- javascript × 35
- owin × 35
- asynchronous × 30
- monad × 28
- ocaml × 28
- tutorial × 27
- warp × 27
- haskell × 26
- sitelet × 25
- linq × 22
- workflows × 22
- wpf × 20
- fpish × 19
- introduction × 19
- silverlight × 19
- sitelets × 19
- monodevelop × 17
- rpc × 17
- suave × 17
- piglets × 16
- collections × 15
- feature request × 15
- jquery × 15
- templates × 15
- getting started × 14
- pipeline × 14
- kendoui × 13
- reactive × 12
- 4.1.0.171 × 11
- monads × 11
- opinion × 10
- 4.0.190.100-rc × 9
- deployment × 9
- fixed × 9
- formlets × 9
- in × 9
- json × 9
- plugin × 9
- proposal × 9
- scheme × 9
- solid × 9
- basics × 8
- concurrent × 8
- highcharts × 8
- how-to × 8
- python × 8
- 4.1.1.175 × 7
- complexity × 7
- documentation × 7
- visual studio × 7
- 4.1.2.178 × 6
- lisp × 6
- real-world × 6
- released in 4.0.192.103-rc × 6
- remoting × 6
- resources × 6
- scala × 6
- websharper ui.next × 6
- workshop × 6
- xaml × 6
- 4.0.193.110 × 5
- 4.2.3.236 × 5
- aspnetmvc × 5
- authentication × 5
- azure × 5
- bootstrap × 5
- conference × 5
- dsl × 5
- formlet × 5
- java × 5
- list × 5
- metaprogramming × 5
- ml × 5
- released in Zafir.4.0.188.91-beta10 × 5
- sql × 5
- visualstudio × 5
- websharper.forms × 5
- zafir × 5
- 4.0.192.106 × 4
- 4.0.195.127 × 4
- 4.1.0.38 × 4
- 4.2.1.86 × 4
- 4.2.6.118 × 4
- css × 4
- example × 4
- extensions × 4
- fsi × 4
- fsx × 4
- html5 × 4
- jqueryui × 4
- lift × 4
- reflection × 4
- remote × 4
- rest × 4
- spa × 4
- teaching × 4
- template × 4
- websocket × 4
- wontfix × 4
- 4.0.196.147 × 3
- 4.1.0.34 × 3
- 4.1.6.207 × 3
- 4.2.1.223-beta × 3
- 4.2.11.258 × 3
- 4.2.4.114 × 3
- 4.2.4.247 × 3
- 4.2.5.115 × 3
- 4.2.6.253 × 3
- 4.2.9.256 × 3
- ajax × 3
- alt.net × 3
- aml × 3
- asp.net mvc × 3
- canvas × 3
- cloudsharper × 3
- compilation × 3
- database × 3
- erlang × 3
- events × 3
- extension × 3
- file upload × 3
- forums × 3
- inline × 3
- issue × 3
- kendo × 3
- macro × 3
- mono × 3
- msbuild × 3
- mvc × 3
- pattern × 3
- piglet × 3
- released in Zafir.4.0.187.90-beta10 × 3
- svg × 3
- type provider × 3
- view × 3
- 4.1.1.64 × 2
- 4.1.5.203 × 2
- 4.1.7.232 × 2
- 4.2.10.257 × 2
- 4.2.3.111 × 2
- 4.2.5.249 × 2
- android × 2
- asp.net × 2
- beginner × 2
- blog × 2
- chart × 2
- client × 2
- client server app × 2
- clojure × 2
- computation expressions × 2
- constructor × 2
- corporate × 2
- courses × 2
- cufp × 2
- d3 × 2
- debugging × 2
- direct × 2
- discriminated union × 2
- docs × 2
- elm × 2
- endpoint × 2
- endpoints × 2
- enterprise × 2
- entity framework × 2
- event × 2
- f# interactive × 2
- fable × 2
- flowlet × 2
- formdata × 2
- forms × 2
- fsc × 2
- google maps × 2
- hosting × 2
- http × 2
- https × 2
- iis 8.0 × 2
- install × 2
- interactive × 2
- interface × 2
- iphone × 2
- iteratee × 2
- jobs × 2
- jquery mobile × 2
- keynote × 2
- lens × 2
- lenses × 2
- linux × 2
- listmodel × 2
- mac × 2
- numeric × 2
- oauth × 2
- obfuscation × 2
- offline × 2
- oop × 2
- osx × 2
- packaging × 2
- pattern matching × 2
- performance × 2
- pipelines × 2
- q&a × 2
- quotation × 2
- reference × 2
- released in Zafir.4.0.185.88-beta10 × 2
- rx × 2
- script × 2
- security × 2
- self host × 2
- seq × 2
- sockets × 2
- stm × 2
- tcp × 2
- trie × 2
- tutorials × 2
- type × 2
- url × 2
- var × 2
- websharper.charting × 2
- websharper4 × 2
- websockets × 2
- wig × 2
- xna × 2
- zh × 2
- .net interop × 1
- 2012 × 1
- 4.0.194.126 × 1
- 4.1.3.184 × 1
- 4.1.4.189 × 1
- 4.2.0.214-beta × 1
- 4.2.12.259 × 1
- 4.2.2.231-beta × 1
- 4.2.8.255 × 1
- Canvas Sample Example × 1
- DynamicStyle Animated Style × 1
- Fixed in 4.0.190.100-rc × 1
- Released in Zafir.UI.Next.4.0.169.79-beta10 × 1
- SvgDynamicAttribute × 1
- WebComponent × 1
- abstract class × 1
- accumulator × 1
- active pattern × 1
- actor × 1
- addin × 1
- agents × 1
- aggregation × 1
- agile × 1
- alter session × 1
- animation × 1
- anonymous object × 1
- apache × 1
- api × 1
- appcelerator × 1
- architecture × 1
- array × 1
- arrays × 1
- asp.net 4.5 × 1
- asp.net core × 1
- asp.net integration × 1
- asp.net mvc 4 × 1
- asp.net web api × 1
- aspnet × 1
- ast × 1
- attributes × 1
- authorization × 1
- b-tree × 1
- back button × 1
- badimageformatexception × 1
- bash script × 1
- batching × 1
- binding-vars × 1
- bistro × 1
- body × 1
- bundle × 1
- camtasia studio × 1
- cas protocol × 1
- charts × 1
- clarity × 1
- class × 1
- cli × 1
- clipboard × 1
- clojurescript × 1
- closures × 1
- cloud × 1
- cms × 1
- coding diacritics × 1
- color highlighting × 1
- color zones × 1
- combinator × 1
- combinators × 1
- compile × 1
- compile code on server × 1
- config × 1
- confirm × 1
- content × 1
- context × 1
- context.usersession × 1
- continuation-passing style × 1
- coords × 1
- cordova × 1
- cors × 1
- coursera × 1
- cross-domain × 1
- csla × 1
- current_schema × 1
- custom content × 1
- data × 1
- data grid × 1
- datetime × 1
- debug × 1
- declarative × 1
- delete × 1
- devexpress × 1
- dhtmlx × 1
- dictionary × 1
- directattribute × 1
- disqus × 1
- distance × 1
- do binding × 1
- doc elt ui.next upgrade × 1
- docker × 1
- dojo × 1
- dol × 1
- dom × 1
- domain × 1
- du × 1
- duf-101 × 1
- dynamic × 1
- eastern language × 1
- eclipse × 1
- edsl × 1
- em algorithm × 1
- emacs × 1
- emotion × 1
- enums × 1
- error × 1
- etw × 1
- euclidean × 1
- eventhandlerlist × 1
- examples × 1
- ext js × 1
- extension methods × 1
- extra × 1
- facet pattern × 1
- failed to translate × 1
- fake × 1
- fantomas × 1
- fear × 1
- float × 1
- form × 1
- form-data × 1
- forum × 1
- fp × 1
- frank × 1
- fsdoc × 1
- fsharp × 1
- fsharp.core × 1
- fsharp.powerpack × 1
- fsharpx × 1
- fsunit × 1
- function × 1
- functional style × 1
- game × 1
- games × 1
- gc × 1
- generic × 1
- geometry × 1
- getlastwin32error × 1
- getting-started × 1
- google × 1
- google.maps × 1
- grid × 1
- group × 1
- guide × 1
- hash × 1
- headers × 1
- hello world example × 1
- heroku × 1
- highchart × 1
- history × 1
- how to × 1
- html-templating × 1
- http405 × 1
- httpcontext × 1
- hubfs × 1
- i18n × 1
- ie 8 × 1
- if-doc × 1
- iis × 1
- image × 1
- images × 1
- inheritance × 1
- initialize × 1
- input × 1
- install "visual studio" × 1
- installer × 1
- int64 × 1
- interfaces × 1
- internet explorer × 1
- interop × 1
- interpreter × 1
- io × 1
- iobservable × 1
- ios × 1
- iot × 1
- ipad × 1
- isomorphic × 1
- javascript optimization × 1
- javascript semanticui resources × 1
- jquery-plugin × 1
- jquery-ui × 1
- jquery-ui-datepicker × 1
- js × 1
- kendo datasource × 1
- kendochart × 1
- kendoui compiler × 1
- knockout × 1
- l10n × 1
- learning × 1
- library × 1
- libs × 1
- license × 1
- licensing × 1
- lineserieszonescfg × 1
- local setting × 1
- localization × 1
- logging × 1
- loop × 1
- macros × 1
- mailboxprocessor × 1
- mapping × 1
- maps × 1
- markerclusterer × 1
- markup × 1
- marshal × 1
- math × 1
- mathjax × 1
- message × 1
- message passing × 1
- message-passing × 1
- meta × 1
- metro style × 1
- micro orm × 1
- minimum-requirements × 1
- mix × 1
- mobile installation × 1
- mod_mono × 1
- modal × 1
- module × 1
- mouseevent × 1
- mouseposition × 1
- multidimensional × 1
- multiline × 1
- multithreading × 1
- mysql × 1
- mysqlclient × 1
- nancy × 1
- native × 1
- nested × 1
- nested loops × 1
- node × 1
- nunit × 1
- object relation mapper × 1
- object-oriented × 1
- om × 1
- onboarding × 1
- onclick × 1
- optimization × 1
- option × 1
- orm × 1
- os x × 1
- output-path × 1
- override × 1
- paper × 1
- parameter × 1
- persistence × 1
- persistent data structure × 1
- phonegap × 1
- pola × 1
- post × 1
- powerpack × 1
- prefix tree × 1
- principle of least authority × 1
- privacy × 1
- private × 1
- profile × 1
- programming × 1
- project × 1
- project euler × 1
- projekt_feladat × 1
- protected × 1
- provider × 1
- proxy × 1
- ptvs × 1
- public × 1
- pure f# × 1
- purescript × 1
- qna × 1
- quant × 1
- query sitelet × 1
- question × 1
- quotations × 1
- range × 1
- raphael × 1
- razor × 1
- rc × 1
- reactjs × 1
- real-time × 1
- ref × 1
- region × 1
- released in 4.0.190.100-rc × 1
- reporting × 1
- responsive design × 1
- rest api × 1
- rest sitelet × 1
- restful × 1
- round table × 1
- router × 1
- routing × 1
- rpc reverseproxy × 1
- runtime × 1
- sales × 1
- sample × 1
- sampleapp × 1
- scriptcs × 1
- scripting × 1
- search × 1
- self hosted × 1
- semanticui × 1
- sequence × 1
- serialisation × 1
- service × 1
- session-state × 1
- sharepoint × 1
- signals × 1
- sitelet website × 1
- sitelet.protect × 1
- sitlets × 1
- slickgrid × 1
- source code × 1
- sqlentityconnection × 1
- ssl × 1
- standards × 1
- static content × 1
- stickynotes × 1
- streamreader × 1
- stress × 1
- strong name × 1
- structures × 1
- submitbutton × 1
- subscribe × 1
- svg example html5 websharper.ui.next × 1
- sweetalert × 1
- system.datetime × 1
- system.reflection.targetinvocationexception × 1
- table storage × 1
- targets × 1
- tdd × 1
- templates ui.next × 1
- templating × 1
- text parsing × 1
- three.js × 1
- time travel × 1
- tls × 1
- tooltip × 1
- tracing × 1
- tsunamiide × 1
- turkish × 1
- twitter-bootstrap × 1
- type erasure × 1
- type inference × 1
- type providers × 1
- type-providers × 1
- typeprovider × 1
- ui next forms × 1
- ui-next × 1
- ui.next jqueryui × 1
- ui.next charting × 1
- ui.next formlets × 1
- ui.next forms × 1
- ui.next suave visualstudio × 1
- ui.next templating × 1
- unicode × 1
- unittest client × 1
- upload × 1
- usersession × 1
- validation × 1
- vb × 1
- vb.net × 1
- vector × 1
- view.map × 1
- visal studio × 1
- visual f# × 1
- visual studio 11 × 1
- visual studio 2012 × 1
- visual studio shell × 1
- vs2017 compiler zafir × 1
- vsix × 1
- web api × 1
- web-scraping × 1
- webapi × 1
- webcomponents × 1
- webforms × 1
- webgl × 1
- webrtc × 1
- webshaper × 1
- websharper async × 1
- websharper codemirror × 1
- websharper f# google × 1
- websharper forms × 1
- websharper reactive × 1
- websharper rpc × 1
- websharper sitelets routing × 1
- websharper warp × 1
- websharper-interface-generator × 1
- websharper.chartsjs × 1
- websharper.com × 1
- websharper.exe × 1
- websharper.owin × 1
- websharper.ui.next × 1
- websharper.ui.next jquery × 1
- websockets iis × 1
- why-websharper × 1
- windows 7 × 1
- windows 8 × 1
- windows-phone × 1
- winrt × 1
- www.grabbitmedia.com × 1
- xamarin × 1
- xml × 1
- yeoman × 1
- yield × 1
- zafir beta × 1
- zafir websharper4 × 1
- zarovizsga × 1
![]() |
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 |
Hi everyone, this is the first time I have had something that I felt I should post. And even now I'm a bit nervous. Well I'll get into the heart of the subject.
I have been looking at functional reactive animation. An I got to thinking how difficult would it be to implement arrows in F#. Well it seems not to be that difficult because here is a preliminary try.
#lightmodule Arrow = type Arrow<'inp, 'out> (f:'inp -> 'out) = member a.run x = f x let arr f = new Arrow<'i,'o>(f) let op_RightShift (f:Arrow<'inp,'mid>) (g:Arrow<'mid,'out>) = arr (fun x -> g.run(f.run x)) let (&&&) (f:Arrow<'b,'c>) (g:Arrow<'b,'d>) = arr (fun i -> (f.run i, g.run i)) let first (f:Arrow<'a, 'b>) = arr (fun (i,x) -> ( f.run i, x)) let second (f:Arrow<'a, 'b>) = let swap (x,y) = (y,x) (arr swap) >>> (first f) >>> (arr swap) let ( *** ) (f:Arrow<'a,'b>) (g:Arrow<'c,'d>) = (first f) >>> (second g)
Disclaimer: I am a professional amateur. So this code may not be completely correct. However, comment are welcome and appreciated.