As already suggested above, you'd better use seq instead of list. I just fired up fsi and got the code below, maybe not as elegant as you expect but should be just fine. Btw, what's the correct answer? I'm too lazy to register to play with euler.
1 2 3 4 5 6 7
> let rec fibs a b = { if a > 1000000 then yield! [] else if a%2 = 0 then yield a yield! fibs b (a+b) } in fibs 1 1 |> Seq.fold1 (+);; val it : int = 1089154
Thank you all for the answers, they helped a lot. I do realise that lists are not the ideal type for that kind of calculation but with some (extremely minor) modifications to d2bg's code I got myself a list.
1 2 3 4 5 6 7
let rec fiblist a b = [if a > 1000000 then yield! [] else if a%2 = 0 then yield a yield! fiblist b (a+b)] print_any (fiblist 1 1)
[2; 8; 34; 144; 610; 2584; 10946; 46368; 196418; 832040]
I feel I'm starting to get a hang of lists and the different way you can create and modify them. Atleast the basics. I do have some follow up questions though:
1. yield and yield!, I have no experience with those from before and I found little resources when I searched around. Anyone know a good basic description on how they work and their general purpose, for example do they exists in a similar way in oCaml so I can find a book on that subject where they are described?
2. When are lists better to use than arrays? I know arrays are better when it comes to lookup but is there a similar way these singly-linked lists are clearly better so I should choose one instead of an array to solve a particular type of problem?
3. There exists three different implementations of fold_left (fold1_left, fold_left, fold_left2), is there any practical difference between them?
Thank you again for all the help.
(Yes, 1089154 is the correct answer to the problem)
<i><b>3. There exists three different implementations of fold_left (fold1_left, fold_left, fold_left2), is there any practical difference between them?</b><i> fold_left is the "standard" folding function that takes a list of elements <code lang=fsharp>[i0, i1, ..., in]</code> and a starting value <c>s</c>. Then, it runs the following computation, returning the answer: <code lang=fsharp>f (... (f (f s i0) i1) ...) in</code>. fold1_left is similar to fold_left, except that it doesn't take a seed value. Instead, it uses the first element of the list as the seed. So, it return the final answer for: <code lang=fsharp>f (... (f (f i0 i1) i2) ...) in</code>. fold_left2 is the same as fold_left, except that it works on 2 lists simultaneously. So, the function <c>f</c> that it takes must take 3 arguments instead of 2. It's calculation is of the form: <code lang=fsharp>f (... (f (f s i0 j0) i1 j1) ...) in jn</code>. Note that the 2 lists should be of the same length to avoid exceptions and other runtime errors. So, in effect, it depends on what you want to do. The majority of the time, I've only used the standard fold_left, but that's mainly because I haven't needed the other 2. I'd say they mainly serve as "syntactic sugar", as you have do everything you need with just fold_left. <b>EDIT:</b> If you look at the source code for list.fs that comes with the F# distribution, you will see that fold1_left is actually implemented using fold_left. On the other hand, fold_left2 has a free-standing implementation. Regards, z.
Ah, I see. Thank you for the explanation. I had not even thought of actually looking at the source code before, good tip.
By the way, I found a nice explanation of yield and yield! at Tomasp's site:
List's are actually a bad idea for this problem, the reason Seq's are so useful here is that the actual elements of the Seq aren't stored in memory but are calculated as we need them so we never actually store the Fibonacci numbers, which would be a bad thing since we are only interested in the sum. With list's, however, the values are stored by the list so we would be creating a list of one million elements when we don't need to.
Chris's solution in the blog can actually be made slightly simpler, all we are after is the sum smaller then one million so it doesn't actually matter weather the Seq contains one million elements or ten million elements as long as there is enough for the sum to pass one million. In addition, because, Seq's aren't stored in memory there's nothing to stop us from creating an infinite sequence with all of the numbers of the fibonacci sequence (this is mentioned at the end of the blog) so you could just do:
let problem2 =
(1,1)
|> Seq.unfold (fun (n0,n1) -> Some (n0, (n1, n0 + n1)))
|> Seq.fold
(fun acc x ->
if x % 2 = 0 && x < 1000000 then
acc + x
else
acc) 0
Edit: I just noticed I misread the question but I'll leave this post anyway.
First off, I'm glad to see that people actually do read my blog :)
I've written up a quick solution to the generation step:
// Gets the next number in the fibonacci sequence given the previous sequence in reverse
let genNextFib reverseFibs = [List.hd reverseFibs + List.hd (List.tl reverseFibs)] @ reverseFibs
// Generates the first x fibonacci numbers as a list, in reverse
let rec getFibsAsList x =
match x with
| x when x < 1 -> failwith "Error: x must be positive"
| 1 -> [1];
| 2 -> [1;1];
| 3 -> [2;1;1];
| 4 -> [3;2;1;1]
| x -> genNextFib (getFibsAsList (x - 1))
/// Calculates the list of fibonacci numbers less that 1E6
let mutable i = 1
let mutable fibsList = [1]
while fibsList.Head < 1000000 do
fibsList <- getFibsAsList i
i <- i + 1
// Reverse it
fibsList <- List.rev fibsList
The biggest challenge when working with lists is to avoid unnessecarily itterating through the elements (wasting time) and to take advantage of tail recursion (wasting stack space). Consider the following code (but please, don't put it into fsi.exe!)
let rec getLastTwoOfList list =
match list with
| first :: second :: [] -> (first, second)
| first :: second :: third -> getLastTwoOfList list.Tail
| _ -> failwith "List should have at least two elements."
(* Don't use this, will chew up stack space and crash fsi.exe!*)
let rec getFibList x =
match x with
| high when high > 100 -> failwith "Will cause stack overflow..."
| _ when x < 1 -> failwith "Error: x must be positive"
| 1 -> [1]
| 2 -> [1;1]
| 3 -> [1;1;2]
| 4 -> [1;1;2;3]
| x -> let allFibsBefore = getFibList (x - 1)
let (x_minus_1, x_minus_2) = getLastTwoOfList allFibsBefore
allFibsBefore @ [x_minus_1 + x_minus_2]
Although perhaps a tad easier to understand and read, the problem here is that 1.) it is slow. Notice that since the fib list is kept in order, to get the last two elements you are forced to walk through each element of the list. Which is on order O(n^2) to generate the first n elements. Also, it isn't tail recursive so you run the risk of a StackOverflow. (Jomo's Blog has a great post on Tail Recursion.)
Hope that helps!
-Chris
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 |
As someone who is both new to F# and functional programming I'm sure I'm asking stupid questions, but here we go anyway.
I've solved the Euler problem number 2 iteratively but in my attemt to start learning to actually use the functional part of F# I want to try to learn the basics. First stop is Lists and related functions. I saw this solution using Seq:
[link:blogs.msdn.com]
and I'm wondering what the most elegant way to solve it using lists is? The problem is:
"Each new term in the Fibonacci sequence is
generated by adding the previous two terms. By starting with 1 and 2,
the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
Find the sum of all the even-valued terms in the sequence which do not exceed one million."I could use filter and fold to get the sum of only the uneven and it is not hard to initiate a list with for example the 10 first numbers in the fibonacci series. But is there a way to fill a list from 1 to n<1 million where the steps are unknown and changing?