Yeah, F# is poor at break and continue. You goaded me into authoring them, though:
#light
// Author a continuation monad to provide non-local control flow
type ContinuationBuilder() =
member this.Return(x) = (fun k -> k x)
member this.Let(x,f) = f x
member this.Bind(m,f) = (fun k -> m (fun a -> f a k))
member this.Delay(f) = (fun k -> f () k)
member this.Combine(m1,m2) = this.Bind(m1, fun() -> m2)
member this.Zero() = (fun k -> k())
member this.Execute(m) = m id
member this.CallCC(f) = (fun origK -> f origK origK)
let K = new ContinuationBuilder()
// Define a C-style "for" loop
let CStyleFor init test update body =
K.CallCC (fun origK -> K {
init()
let _break = (fun k -> origK ())
let rec TestBodyLoop = K {
if test() then
do! body _break _continue
do! _continue }
and _continue = K {
update()
do! TestBodyLoop }
do! TestBodyLoop })
let i = ref 0
let a = [| 0 .. 10 |]
(*
for(i = 0; i < 10; ++i) {
printf("n=%d", a[ i]);
if (i==2)
continue;
printf("once again, n=%d", a[ i]);
if (i==4)
break;
printf("once more, n=%d", a[ i]);
}
*)
K.Execute(K { do! CStyleFor (fun()-> i:=0) (fun()-> !i<10) (fun()-> i:=!i+1) (fun _break _continue -> K {
printfn "n=%d" a.[!i]
if !i = 2 then
do! _continue
printfn "once again, n=%d" a.[!i]
if !i = 4 then
do! _break
printfn "once more, n=%d" a.[!i]
})})
I have to admit, I have no idea how this code works :) What chapter(s) in Expert F# discusses such techniques? Or if you have external links that discuss techniques such as this I'd be interested.
Also, is there a technical limitation that prevents F# from supporting break/continue? It seems like even if break/continue could not be supported, it would still be easily achievable if the for looping construct supported more advanced expressions. For example,
Would express one of the loops, and you could nest similar blocks inside of each other to achieve the desired result.
Also, is there a technical limitation that prevents F# from supporting break/continue? It seems like even if break/continue could not be supported, it would still be easily achievable if the for looping construct supported more advanced expressions. For example,
for (i in 1..10) && (not stop) do
if ( i * product_so_far > N) then stop := true
else if (not already_seen_this_i) then
//do stuff
Would express one of the loops, and you could nest similar blocks inside of each other to achieve the desired result.
I have to admit, I have no idea how this code works :) What chapter(s) in Expert F# discusses such techniques? Or if you have external links that discuss techniques such as this I'd be interested.
Also, is there a technical limitation that prevents F# from supporting break/continue? It seems like even if break/continue could not be supported, it would still be easily achievable if the for looping construct supported more advanced expressions. For example,for (i in 1..10) && (not stop) do if ( i * product_so_far > N) then stop := true else if (not already_seen_this_i) then //do stuff
Would express one of the loops, and you could nest similar blocks inside of each other to achieve the desired result.
The same can be expressed more functionally as
1..10 |> Seq.takeWhile((*) product_so_far >> (<) N) |> Seq.filter(fun _ -> not already_seen_this_i) |> Seq.iter(fun i -> (*do stuff*))
Actually you need to be careful with composition and (<) and (>). I believe you mean:
That is,
1..10 |> Seq.takeWhile((*) product_so_far >> (<b>></b>) N) |> Seq.filter(fun _ -> not already_seen_this_i) |> Seq.iter(fun i -> (*do stuff*))
That is,
N (>) product_so_far:-)
That is,Well, is that the code divisortheory posted ;) ?N (>) product_so_far:-)
That is,Well, is that the code divisortheory posted ;) ?N (>) product_so_far:-)
mau was responding to eventhelix, who uses (<) instead of (>). It's easy to confuse these when chaning infix to prefix.
mau was responding to eventhelix, who uses (<) instead of (>).And that's correct, isn't it? eventhelix preserved the semantics of divisortheory's code, whereas mau flipped it by not flipping the operator.
So yes, I wholeheartedly agree with you. As long as F# doesn't support operator sections, it's not worth the hassle and confusion.
I borrowed the syntax from J for this kind of situation:
it is '<&3' in J but '&' is taken and the () is needed for '<'
let (&.) f x = fun y -> f y x let lessthan3 = (<)&.3
it is '<&3' in J but '&' is taken and the () is needed for '<'
In the interest of preferring sanity to obfuscation, might I suggest that
is better than
(fun x -> x < MAX)
is better than
(>) MAX (flip << (<)) MAX (<) &. MAX etc.
In the interest of preferring sanity to obfuscation, might I suggest that(fun x -> x < MAX)
is better than(>) MAX (flip << (<)) MAX (<) &. MAX etc.
I used to incline to think in this way but after spending some time with these seemingly like line noise(in J) and also the frequently used flip, circle( f.g) point free style in Haskell, I do think there are advantages.
The analogy is a bit like English vs Chinese.
I very nearly have no idea how it works either. :) I just use [link:www.haskell.org] and some intuition; my brain knows how to tell my fingers to type this code, but is hasn't yet let me in on what the heck is going on. :)
I don't think there are necessarily any technical limitations; 'break' and 'continue' are reserved words, so I imagine some future version of the language will support them, it's just a matter of priorities. (I am not sure if/how the keywords would interact with the computation expression 'builder' methods 'For' and 'While'.)
I don't think there are necessarily any technical limitations; 'break' and 'continue' are reserved words, so I imagine some future version of the language will support them, it's just a matter of priorities. (I am not sure if/how the keywords would interact with the computation expression 'builder' methods 'For' and 'While'.)
Hi,
Just as a side-note, I implemented a more syntactically pleasant version of the computation expression builder that let's you write 'break' and 'continue' in F#. This downside is that it is a computation expression, which is translated into member calls that take lambda functions as arguments, so it probably won't be very efficient.
However, if you're looking for a nice way to write this, you can take a look at it :-). The code would look like this:
Here are links to the article that describes this:
Just as a side-note, I implemented a more syntactically pleasant version of the computation expression builder that let's you write 'break' and 'continue' in F#. This downside is that it is a computation expression, which is translated into member calls that take lambda functions as arguments, so it probably won't be very efficient.
However, if you're looking for a nice way to write this, you can take a look at it :-). The code would look like this:
imperative {
for i in 0 .. (list1_count - 1) do
for j in 0 .. (list2_count - 1) do
if (l2.[j] = l1.[ i]) then do! continue
let temp = l1.[ i] * l2.[ j]
if (temp >= N) then do! break
for k in 0 .. (list3_count - 1) do
if (l3.[ k] = l2.[ j] || l3.[ k] = l1.[ i]) do! continue
let temp2 = temp*l3.[ k]
if (temp2 >= N) then do! break
set.add(temp*temp2) }
Here are links to the article that describes this:
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 |
The resulting products can be stored in a Set, HashSet, List, doesn't matter as long as there are no duplicates. I came up with something, but it's absolutely horrendous looking, and I'm having a lot of difficulty expressing this in a way that isn't horrendous. In C++ or something it would be really simple, I could just do this:
for (int i=0; i < list1_count; ++i) { for (int j=0; j < list2_count; ++j) { if (l2 [ j] == l1 [ i]) continue; int temp = l1 [ i] * l2 [ j]; if (temp >= N) break; for (int k=0; k < list3_count; ++k) { if (l3 [ k] == l2 [ j] || l3 [ k] == l1 [ i]) continue; int temp2 = temp*l3 [ k]; if (temp2 >= N) break; set.add(temp*temp2); } } }But I'm having some difficulty writing this same code in F#. If they were stored in an array, I could use imperative code to basically mimic the above with mutable index variables, but with lists the combination of breaks, continues, and duplicate checking is making this a little difficult.