Great sample!
You can define structural comparison for new type definitions. I've opened a blog entry on this topic.
DOn
You can define structural comparison for new type definitions. I've opened a blog entry on this topic.
DOn
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 must admit, not having ml's functors or haskell's type classes makes implementing data structures a tad painful.
My first draft was a simple literal translation of the book's code using the structural comparision operators (<) (<=). I then changed it to have the heap type carry around it's comparision function.
(As mentioned in the Red-Black tree thread) I agree that the attempt at faking a functor by generating a collection of closures, (Set.make) is not as good as passing around the comparator.
Am I correct in thinking that the structural comparision operators are a very thin layer over the IL and there would be no way to custom implement the structural comparision function for user defined f# types (other than using a class)?
"Primitives.CompilerSpecific.StructuralCompareFast" is the comparator for something like
type ('a,'b) either = Left of 'a | Right of 'aAnd provides the comparision for any type defined like this? (gives slightly interesting behaviour at times).
While i'm getting things off my chest... a pet peive of mine is comparision functions returning int's. It drives me nuts in Java, it's just not declarative enough or clear about the comparision. Maybe someone can show me a way decent way to use it. My solution.. use the SML way
Anyway here is the code :
module BinomialHeap type ord = LT | EQ | GT type 'a comparer = 'a -> 'a -> ord type 'a tree = Node of int * 'a * 'a tree list type 'a heap = { cf : 'a comparer ; heap : 'a tree list } let basic_compare x1 x2 = let a = Pervasives.compare x1 x2 in if a < 0 then LT else if a > 0 then GT else EQ let empty_custom cf = { cf = cf ; heap = [] } let empty = {cf=basic_compare; heap = []} let isEmpty {heap=heap} = heap = [] let rank (Node (r,_,_)) = r let root (Node (_,x,_)) = x let link cf (Node (r, x1, c1) as t1) (Node (_, x2, c2) as t2) = match cf x1 x2 with | GT -> Node (r+1, x2, t1 :: c2) | _ -> Node (r+1, x1, t2 :: c1) let rec insTree cf (t: 'a tree) ts = match ts with | [] -> [t] | t'::ts' -> match basic_compare (rank t) (rank t') with | LT -> t::ts | _ -> insTree cf (link cf t t') ts' let insert x {cf=cf;heap=heap} = let newheap = insTree cf (Node (0, x, [])) heap in {cf=cf; heap=newheap} let rec merge' cf treepair = match treepair with | (ts1, []) -> ts1 | ([], ts2) -> ts2 | ((t1::ts1' as ts1), (t2::ts2' as ts2)) -> match basic_compare (rank t1) (rank t2) with | LT -> t1 :: (merge' cf (ts1', ts2)) | GT -> t2 :: (merge' cf (ts1, ts2')) | EQ -> insTree cf (link cf t1 t2) (merge' cf (ts1', ts2')) let merge {cf=cf;heap=heap1} {heap=heap2} = let newheap = merge' cf (heap1, heap2) in {cf=cf;heap=newheap} exception Empty_Heap let rec removeMinTree cf heap = match heap with | [] -> raise Empty_Heap | [t] -> (t, []) | (t::ts) -> let (t', ts') = removeMinTree cf ts in match cf (root t) (root t') with | LT | EQ -> (t, ts) | _ -> (t', t::ts') let findMin {cf=cf;heap=heap} = let (t, _) = removeMinTree cf heap in root t let removeMin {cf=cf;heap=heap} = let (Node (_, x, ts1), ts2) = removeMinTree cf heap in (x, {cf=cf; heap=(merge' cf ((List.rev ts1), ts2))}) let deleteMin heap = snd (removeMin heap) )isEmpty = O(1)
insert = O(1) amortized (O(log n) worst case)
merge = O(log n)
findMin, removeMin, deleteMin = O(log n)
findMin can be O(1) if we store the smallest element separately
Chris Okasaki goes into great depth about variations of binomial heaps, using lazyness to give better guarentees about amortized time bounds, and a variation that gives merge in O(1) !.
Binomial heaps improve over vanilla heaps on insert and merge operations. O(1) rather than O(log n) and O(log n) rather than O(n) respectively.
Fibonacci Heaps sound like a good topic to continue with another time ;).