hubris 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/.gitignore +31 -0
  2. data/.rvmrc +2 -0
  3. data/Gemfile +11 -0
  4. data/Haskell/Hubrify.hs +69 -0
  5. data/Haskell/LICENSE +22 -0
  6. data/Haskell/Language/Ruby/Foo.hs +20 -0
  7. data/Haskell/Language/Ruby/Hubris/Binding.hsc +214 -0
  8. data/Haskell/Language/Ruby/Hubris/GHCBuild.hs +46 -0
  9. data/Haskell/Language/Ruby/Hubris/Hash.hs +27 -0
  10. data/Haskell/Language/Ruby/Hubris/Interpolator.hs +22 -0
  11. data/Haskell/Language/Ruby/Hubris/LibraryBuilder.hs +181 -0
  12. data/Haskell/Language/Ruby/Hubris/ZCode.hs +68 -0
  13. data/Haskell/Language/Ruby/Hubris.hs +254 -0
  14. data/Haskell/Language/Ruby/Wrappers.hs +32 -0
  15. data/Haskell/Language/Ruby/testLib.hs +9 -0
  16. data/Haskell/Setup.hs +31 -0
  17. data/Haskell/cbits/rshim.c +46 -0
  18. data/Haskell/cbits/rshim.h +50 -0
  19. data/Haskell/hubris.cabal +53 -0
  20. data/INSTALL +21 -0
  21. data/Manifest.txt +22 -0
  22. data/PostInstall.txt +1 -0
  23. data/README.markdown +107 -0
  24. data/Rakefile +46 -43
  25. data/VERSION +1 -0
  26. data/doc/CommonErrors.txt +18 -0
  27. data/doc/CommonErrors.txt~HEAD +18 -0
  28. data/doc/don_feedback.txt +25 -0
  29. data/doc/haskell-hubris.tex +242 -0
  30. data/doc/new_interface.rb +74 -0
  31. data/doc/ruby-hubris.tex +176 -0
  32. data/doc/wisdom_of_ancients.txt +55 -0
  33. data/ext/hubris.rb +4 -0
  34. data/ext/stub/extconf.rb +5 -0
  35. data/ext/{HubrisStubLoader.c → stub/stub.c} +1 -1
  36. data/hubris.gemspec +31 -0
  37. data/lib/Makefile +181 -0
  38. data/lib/hubris/version.rb +3 -0
  39. data/lib/hubris.rb +16 -13
  40. data/rspec.rake +21 -0
  41. data/sample/Fibonacci.hs +2 -2
  42. data/sample/config.ru +3 -1
  43. data/script/ci.sh +25 -0
  44. data/script/console +10 -0
  45. data/spec/hubris_spec.rb +173 -47
  46. data/tasks/extconf/stub.rake +43 -0
  47. data/tasks/extconf.rake +13 -0
  48. metadata +118 -27
  49. data/ext/extconf.rb +0 -5
data/README.markdown ADDED
@@ -0,0 +1,107 @@
1
+ # Hubris
2
+
3
+ ## Description
4
+
5
+ Hubris is a bridge between Ruby and Haskell, between love and bondage,
6
+ between slothful indolence and raw, blazing speed. Hubris will wash
7
+ your car, lie to your boss, and salvage your love life. If you are
8
+ very, very lucky, it might also let you get some functional goodness
9
+ into your ruby programs through the back door.
10
+
11
+ I probably don't have to say this, but patches are very much
12
+ welcome. If you have trouble installing it, tell me, and help me
13
+ improve the docs.
14
+
15
+ ## Synopsis
16
+
17
+ The best docs, as ever, are in the tests, but as a quick precis, you
18
+ can use it a little like this:
19
+
20
+ require 'hubris' # best line ever
21
+
22
+ class Target
23
+ hubris :inline =>"triple::Int->Int; triple n = 3*n"
24
+ end
25
+
26
+ t = Target.new
27
+ puts t.triple(10)
28
+ => 30
29
+
30
+ There are a few restrictions. All functions take one argument and
31
+ return one value: this shouldn't be a major problem because you can
32
+ pass arrays of arguments in if you need more. Hubris can currently
33
+ handle numbers, strings, basic types (like nil, true and false),
34
+ arrays and hashes. There will probably be some Ruby structures
35
+ (modules, regular expressions, etc) that won't ever be handled
36
+ natively unless someone can convince me it's a sensible thing to do.
37
+
38
+ Hubris will refuse to compile Haskell code that produces any
39
+ warnings. You can suppress this admittedly fairly strict behaviour by
40
+ passing the ":no_strict => true" flag, but in your heart of hearts
41
+ you'll know you've done the wrong thing.
42
+
43
+ There are also two other modes:
44
+
45
+ hubris :source => "MyCoolModule.hs"
46
+
47
+ which loads a source file on disk (in the same directory as your ruby),
48
+ and
49
+
50
+ hubris :module => "Data.ByteString", :packages => ["bytestring"]
51
+
52
+ which will load the Data.ByteString module which is installed on the
53
+ system. In this case, we also need to let the Haskell side know that
54
+ we'll be using the "bytestring" package, so we pass that too: You may
55
+ need to load extra packages with :inline and :source as well, and
56
+ that's supported.
57
+
58
+
59
+ ## Requirements
60
+
61
+ * ghc 6.10 (to bootstrap 6.12) and cabal-install. This comes with the
62
+ Haskell Platform
63
+ * ruby 1.8.6 or higher (most heavily tested on 1.9.1)
64
+ * Linux or Mac. See
65
+ <http://www.shimweasel.com/2009/09/14/unprincipled-skulduggery-with-ghc-6-12-dylibs-on-mac-os-x>
66
+ and the following entry for more info on the Mac build.
67
+ * zsh or bash
68
+ * git
69
+
70
+ ## Install
71
+
72
+ Better instructions for [Linux](http://wiki.github.com/mwotton/Hubris/installation-of-ghc-6121-on-ubuntu-910) and [Mac](http://wiki.github.com/mwotton/Hubris/installation-of-ghc-6121-on-mac-os-x)
73
+
74
+ ## Contributors
75
+
76
+ * Mark Wotton
77
+ * James Britt
78
+ * Josh Price
79
+ * Tatsuhiro Ujihisa
80
+
81
+ ## License
82
+
83
+ (The MIT License)
84
+
85
+ Copyright (c) 2009 Mark Wotton
86
+
87
+ Permission is hereby granted, free of charge, to any person obtaining
88
+ a copy of this software and associated documentation files (the
89
+ 'Software'), to deal in the Software without restriction, including
90
+ without limitation the rights to use, copy, modify, merge, publish,
91
+ distribute, sublicense, and/or sell copies of the Software, and to
92
+ permit persons to whom the Software is furnished to do so, subject to
93
+ the following conditions:
94
+
95
+ The above copyright notice and this permission notice shall be
96
+ included in all copies or substantial portions of the Software.
97
+
98
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
99
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
100
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
101
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
102
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
103
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
104
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
105
+
106
+
107
+ [haskell_platform]: http://hackage.haskell.org/platform/
data/Rakefile CHANGED
@@ -1,51 +1,54 @@
1
- require 'rubygems'
2
- #gem 'hoe', '>= 2.1.0'
3
- #require 'hoe'
1
+
2
+
3
+ require 'bundler'
4
+ Bundler::GemHelper.install_tasks
5
+ require 'rake'
4
6
  require 'fileutils'
5
- require './lib/hubris'
6
-
7
- # Hoe.plugin :newgem
8
- # Hoe.plugin :website
9
- # Hoe.plugin :cucumberfeatures
10
-
11
- # Generate all the Rake tasks
12
- # Run 'rake -T' to see list of generated tasks (from gem root directory)
13
- #$hoe = Hoe.spec 'hubris' do
14
- # self.developer 'Mark Wotton', 'mwotton@gmail.com'
15
- # self.rubyforge_name = "hubris"
16
- # self.summary = 'tool to help build .so files from haskell code for use in Ruby via dl'
17
- # self.post_install_message = 'PostInstall.txt'
18
- # self.readme_file = "README.markdown"
19
- # self.history_file = "HISTORY.markdown"
20
- #end
21
-
22
- #require 'newgem/tasks'
23
- # Dir['tasks/**/*.rake'].each { |t| load t }
24
-
25
-
26
- #file "lib/RubyMap.hs" => ["lib/RubyMap.chs"] do
27
- # str = "c2hs -v --cppopts='-I" + Hubris::RubyHeader + "' --cpp=gcc --cppopts=-E --cppopts=-xc lib/RubyMap.chs"
28
- # # print str
29
- # system(str)
30
- #end
31
-
32
- require 'spec'
33
- require 'spec/rake/spectask'
34
-
35
- # desc "Run the specs under spec/"
36
- # all_examples = Spec::Rake::SpecTask.new do |t|
37
- # t.spec_opts = ['--options', "spec/spec.opts"]
38
- # t.spec_files = FileList['spec/*.rb']
7
+
8
+ # require 'rake-compiler'
9
+ require 'rake/extensiontask'
10
+ # require 'rake/extensiontesttask'
11
+
12
+
13
+ # task "build:native" => [:no_extconf, :native, :build] do
14
+ # file = "pkg/stub-#{`cat VERSION`.chomp}.gem"
15
+ # mv file, "#{file.ext}-i686-linux.gem"
39
16
  # end
40
17
 
41
- # task :spec => ["lib/RubyMap.hs"]
18
+
19
+ Rake::ExtensionTask.new('stub')
20
+
21
+ # intended to be called by the gem builder
22
+ task :haskell_compile => [:compile] do
23
+ ghc_version='/usr/local/bin/ghc' # FIXME, should be able to pick
24
+ # this out from somewhere
25
+ # write the Includes file
26
+ pwd =`pwd`.strip
27
+ arch_headers = "#{RbConfig::CONFIG['rubyhdrdir']}/#{RbConfig::CONFIG['arch']}"
28
+ lib_dir = RbConfig::CONFIG['libdir']
29
+ headers = RbConfig::CONFIG['rubyhdrdir']
30
+ File.open("#{pwd}/Haskell/Language/Ruby/Hubris/Includes.hs","w") do |file|
31
+ file.write "module Language.Ruby.Hubris.Includes where
32
+ extraIncludeDirs = [\"#{headers}\", \"#{arch_headers}\"]"
33
+ end
34
+ # command="cd Haskell; cabal update; cabal install
35
+ # --extra-include-dirs=#{RbConfig::CONFIG['rubyhdrdir']}
36
+ # --extra-include-dirs=#{RbConfig::CONFIG['rubyhdrdir']}/#{RbConfig::CONFIG['arch']} --extra-lib-dirs=#{RbConfig::CONFIG['libdir']} --user --enable-shared --with-ghc=#{ghc_version}"
37
+ command="cd Haskell; cabal install --extra-include-dirs=#{arch_headers} --extra-include-dirs=#{headers} --extra-lib-dirs=#{lib_dir} --user --enable-shared --with-ghc=#{ghc_version}"
38
+ result=%x{#{command}}
39
+ raise "ERROR: ran #{command}, got #{result}" unless $?.success?
40
+ end
41
+
42
+ task :no_extconf do
43
+ $gemspec.extensions = []
44
+ end
45
+
46
+ task :default => :haskell_compile
42
47
 
43
48
  task :clean do
44
49
  FileList[File.expand_path("~/.hubris_cache/*"),
45
- 'lib*.so', 'lib/*.o', 'libfoo_*.bundle' ].each do |f|
46
- begin
47
- File.delete(f)
48
- rescue
49
- end
50
+ 'lib*.so', 'lib/*.o' ].each do |f|
51
+ File.delete(f) rescue nil
50
52
  end
51
53
  end
54
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.3
@@ -0,0 +1,18 @@
1
+ this is a quick guide to diagnosing what could be wrong.
2
+
3
+ This:
4
+ """
5
+ /var/folders/Dz/Dz5WpFSZGUaFLA8jp8kT5E+++TM/-Tmp-/working_source.hs:7:7:
6
+ Could not find module `Foreign':
7
+ Perhaps you haven't installed the "dyn" libraries for package
8
+ `base'?
9
+ """
10
+
11
+ indicates that GHC HEAD was not installed correctly. Run something
12
+ like "find /usr/local -iname '*dyn_hi'" to check that the GHC you are
13
+ using has all its dynamic library header files installed. If it
14
+ doesn't, you probably didn't build GHC the right way: check
15
+ http://www.shimweasel.com/2009/09/16/another-awful-hack-to-ghc-6-11
16
+ and
17
+ http://www.shimweasel.com/2009/09/14/unprincipled-skulduggery-with-ghc-6-12-dylibs-on-mac-os-x
18
+ for more info.
@@ -0,0 +1,18 @@
1
+ this is a quick guide to diagnosing what could be wrong.
2
+
3
+ This:
4
+ """
5
+ /var/folders/Dz/Dz5WpFSZGUaFLA8jp8kT5E+++TM/-Tmp-/working_source.hs:7:7:
6
+ Could not find module `Foreign':
7
+ Perhaps you haven't installed the "dyn" libraries for package
8
+ `base'?
9
+ """
10
+
11
+ indicates that GHC HEAD was not installed correctly. Run something
12
+ like "find /usr/local -iname '*dyn_hi'" to check that the GHC you are
13
+ using has all its dynamic library header files installed. If it
14
+ doesn't, you probably didn't build GHC the right way: check
15
+ http://www.shimweasel.com/2009/09/16/another-awful-hack-to-ghc-6-11
16
+ and
17
+ http://www.shimweasel.com/2009/09/14/unprincipled-skulduggery-with-ghc-6-12-dylibs-on-mac-os-x
18
+ for more info.
@@ -0,0 +1,25 @@
1
+ ------------------------------------------------------------------------
2
+
3
+ Hubris
4
+ Ruby calling Haskell
5
+ - inline, dynamically compiled Haskell
6
+ - call precompiled stuff
7
+
8
+ Dream
9
+ Haskell to code would be Cabal package.
10
+ Ruby would be application.
11
+
12
+ FFI preprocessor:
13
+ Does Haskell foreign export
14
+ Generates marshalling boilerplate
15
+
16
+ Haskell code in Ruby
17
+
18
+ ------------------------------------------------------------------------
19
+
20
+ Grammar, parsing, type-driven.
21
+
22
+ Killer demo:
23
+ - Rails site,
24
+ - super clever/ fast/ multicore Haskell code
25
+
@@ -0,0 +1,242 @@
1
+ % Local Variables:
2
+ % compile-command: "/opt/local/bin/pdflatex fp-syd.tex && open fp-syd.pdf"
3
+ % End:
4
+
5
+ \documentclass{beamer}
6
+ \usepackage{listings}
7
+ \usepackage{beamerthemesplit}
8
+
9
+ \title{Hubris}
10
+ \subtitle{A Trojan Horse for Haskell}
11
+ \author{Mark Wotton \textless mwotton@shimweasel.com\textgreater}
12
+ \date{\today}
13
+
14
+ \begin{document}
15
+ \lstset{language=Haskell}
16
+ \section{Two cultures}
17
+ \frame{\titlepage}
18
+
19
+ % \subsection
20
+ \begin{frame}
21
+ \frametitle{I \ding{170} Ruby}
22
+ \begin{itemize}
23
+ \item concise and flexible
24
+ \item Big web community, many libraries
25
+ \item Fun
26
+ \end{itemize}
27
+ \end{frame}
28
+
29
+ \begin{frame}
30
+ \frametitle{I \ding{170} Haskell}
31
+ \begin{itemize}
32
+ \item<1-> Fast (optimised native code, multicore, etc)
33
+ \item<2-> Expressive - type systems don't have to suck.
34
+ \item<3-> Provably safe at compile time
35
+ \end{itemize}
36
+ \end{frame}
37
+
38
+
39
+ \begin{frame}
40
+ \frametitle{So, why do I care?}
41
+ \begin{itemize}
42
+ \item<1-> Make it easier to slap up a quick web interface to cool
43
+ haskell code.
44
+ \item<2-> Get more web-savvy devs into the Haskell community
45
+ \end{itemize}
46
+ \end{frame}
47
+
48
+ \subsection{problems with Haskell}
49
+ \begin{frame}
50
+ \frametitle{heresies}
51
+ \setlength\parskip{0.1in}
52
+
53
+ Haskell web frameworks are still niche.
54
+
55
+ It's an engineering problem, and pretty boring.
56
+
57
+ Haskell devs aren't exactly hard to find, but they don't seem to be
58
+ web guys.
59
+
60
+ \end{frame}
61
+
62
+ \subsection{problems with Ruby}
63
+ \begin{frame}
64
+ \frametitle{lies, damn lies, benchmarks}
65
+ \center{JRuby vs GHC}
66
+ \begin{tabular}{l l l l}
67
+ Program & Time &Memory & Source Size\\ \hline
68
+ reverse-complement &5 &1 &1/4\\
69
+ regex-dna &7 &3 &1/5\\
70
+ binary-trees &8 &7 &1 \\
71
+ k-nucleotide &10 &1 &1/7 \\
72
+ pidigits &18 &18 &2 \\
73
+ n-body &26 &53 &1 \\
74
+ chameneos-redux &30 &24 &1 \\
75
+ fasta &31 &142 &1 \\
76
+ fannkuch &45 &22 &1/4 \\
77
+ spectral-norm &227 &56 &1/3 \\
78
+ mandelbrot &319 &3 &1/2\\
79
+ \end{tabular}
80
+ \end{frame}
81
+
82
+
83
+
84
+ \section{Hubris}
85
+ \begin{frame}
86
+ \frametitle{Peanut butter, meet chocolate}
87
+ Ruby has a heap of web frameworks, convenience libraries, well-tested
88
+ integration with javascript + CSS.
89
+
90
+ \setlength\parskip{0.25in}
91
+
92
+ Haskell is smoking fast with rock solid type safety but a relatively tiny
93
+ community
94
+
95
+ Hubris is my bridge between the two
96
+ \end{frame}
97
+
98
+ \begin{frame}
99
+ \frametitle{Again, WHY?}
100
+ There are seventy bazillion ways of talking between languages.
101
+ \begin{itemize}
102
+ \item Web services
103
+ \item text over pipes
104
+ \item Protocol buffers, Thrift
105
+ \item COM, HOC, etc (binary interfaces)
106
+ \end{itemize}
107
+
108
+ Reasons to do it this way:
109
+ \begin{itemize}
110
+ \item it's fun (for me, anyway)
111
+ \item low fuss - no explicit mapping of function interfaces
112
+ \item easy to explore a library
113
+ \item few dependencies
114
+ \end{itemize}
115
+ \end{frame}
116
+
117
+ \lstset{language=Haskell}
118
+ \subsection{Haskell example}
119
+ \begin{frame}[fragile]
120
+ \frametitle{lazy, statically typed, and pure}
121
+ Collatz.hs
122
+ \begin{lstlisting}
123
+ module Collatz where
124
+ clMax lim = maximumBy (comparing snd) (assocs arr)
125
+ where arr = listArray (1,lim)
126
+ (0:(map depth [2..]))
127
+ step x = if even x
128
+ then div x 2
129
+ else 3 * x + 1
130
+ depth x = 1 + if n <= lim
131
+ then arr ! n
132
+ else depth n
133
+ where n = step x
134
+ \end{lstlisting}
135
+ Hubrify Collatz collatz.dylib Collatz.hs
136
+
137
+ \end{frame}
138
+
139
+ \subsection{wrap it in Ruby}
140
+ \begin{frame}[fragile]
141
+ \frametitle{actually using it}
142
+ \lstset{language=Ruby}
143
+ \begin{lstlisting}
144
+ require Hubris # my favourite line
145
+ module Collatz
146
+ hubris :module => 'collatz'
147
+ end
148
+ puts Collatz.clMax(1000000)
149
+ >> 837799
150
+ \end{lstlisting}
151
+ \end{frame}
152
+
153
+ \subsection{beneath the covers}
154
+ \begin{frame}[fragile]
155
+ \frametitle{on the Haskell side}
156
+ Hubrify loads the given source files and attempts to find the
157
+ passed-in module using the GHC API.
158
+ \lstset{language=Haskell}
159
+ \begin{lstlisting}
160
+ data RValue = T_NIL | T_FIXNUM Int | ...
161
+ type Value = CULong -- imported from Ruby
162
+ class Haskellable a where
163
+ toHaskell :: RValue -> Maybe a
164
+
165
+ class Rubyable a where
166
+ toRuby :: a -> RValue
167
+
168
+ wrap :: (Haskellable a, Rubyable b) ->
169
+ (a -> b) -> (Value -> Value)
170
+ \end{lstlisting}
171
+ \end{frame}
172
+
173
+ \begin{frame}[fragile]
174
+ \frametitle{blah}
175
+ For each top level definition f, we then typecheck.
176
+ \begin{lstlisting}
177
+ (wrap f) T_NIL == T_NIL
178
+ \end{lstlisting}
179
+ if it fits, it's exportable.
180
+
181
+ create a Haskell file exporting each valid function, add a top level
182
+ manifest, and compile into a self-contained dylib.
183
+
184
+ \end{frame}
185
+
186
+ \begin{frame}
187
+ \frametitle{On the ruby side}
188
+ No Haskell-specific information at all.
189
+
190
+ We have a manifest function we need to call to find the names of
191
+ wrapped functions. (Also gives us a convenient point to initialise
192
+ the Haskell runtime)
193
+
194
+ attach all passed functions as methods on the surrounding module
195
+
196
+ \end{frame}
197
+
198
+
199
+ % \frametitle{Predictive}
200
+ \section{Making it less sucky}
201
+ \begin{frame}
202
+ \setlength\parskip{0.1in}
203
+ \frametitle{What's been done}
204
+ caching of Haskell binaries
205
+
206
+ transparent mapping - no boilerplate
207
+
208
+ separation of concerns - no compiler on server
209
+
210
+ ported to GHC
211
+ \end{frame}
212
+
213
+ \begin{frame}
214
+ \frametitle{Still to do}
215
+ one-way bridge, no callbacks to Ruby
216
+
217
+ autoconf support to find ruby libs and includes
218
+
219
+ more serious hammering to find bugs - is it legitimate to dlopen
220
+ multiple haskell dylibs?
221
+
222
+ performance testing
223
+
224
+ \end{frame}
225
+
226
+
227
+ \begin{frame}
228
+ \frametitle{Try it out!}
229
+ install GHC 6.12 release candidate
230
+
231
+ git clone git://github.com/mwotton/HaskellHubris.git
232
+
233
+ git clone git://github.com/mwotton/Hubris.git
234
+
235
+ follow the README
236
+
237
+ tell me what's missing
238
+
239
+ patches very much welcome (thanks to Josh Price, James Britt and Tatsuhiro Ujihisa)
240
+ \end{frame}
241
+
242
+ \end{document}
@@ -0,0 +1,74 @@
1
+ # IDEAS for new interface
2
+
3
+ # option 1 (implicit method name from haskell function)
4
+ class MyClass
5
+ include Hubris
6
+ def_haskell(code)
7
+ end
8
+
9
+ # option 2 (explicit method name)
10
+ class MyClass
11
+ def_haskell(method_name,code)
12
+ end
13
+
14
+ # option 3 ()
15
+ class Module
16
+ include Hubris
17
+ end
18
+
19
+ class MyClass
20
+ inline_haskell "haskell function"
21
+ end
22
+
23
+ # option 4 (more humourous)
24
+ class Module
25
+ include Hubris
26
+ end
27
+
28
+ class MyClass
29
+ hubris "haskell function"
30
+ end
31
+
32
+ #-----------------------------------------
33
+ # include at the module or package level
34
+ #=========================================
35
+ # does importing as_class make sense? no, just include the module
36
+ # when interpreting Haskell module names replace . with ::
37
+
38
+ # importing std module as a ruby module/class
39
+ hubris :package => "containers", :module => "Data.Map", :as => "Data::Map"
40
+
41
+ # importing your own module (defaults to module)
42
+ hubris :package => "mypackage", :module => "MyModule" [, :as => "MyModule"]
43
+
44
+ # implicit package handling (haskell file in my directory)
45
+ hubris :module => "haskell/shit/MyModule"
46
+
47
+ # simpler to implement option, allows more flexibility in Ruby land
48
+ module MyRubyModule
49
+ # :packages is optional, just brings in external packages.
50
+ hubris :module => "Data.Map", :packages => ["containers","foo"]
51
+ # or
52
+ hubris :source => "MyHaskellCode.hs" # , :packages => [ ... ]
53
+ # or
54
+ hubris :inline => "foo x = x * 2"
55
+ end
56
+
57
+
58
+ # alternative
59
+
60
+ Hubris.import :package => "containers", :module => "Data.Map"
61
+
62
+ module MyRubyModule
63
+ include Hubris::Data::Map
64
+ end
65
+
66
+ # alternative2
67
+
68
+ module MyRubyModule
69
+ hubris :package => "containers", :module => "Data.Map"
70
+ end
71
+
72
+
73
+ 6:34:58 PM Josh Price: class Module; def hubris; self.class_eval { def self.h;"hubrified!";end };end;end
74
+ 6:35:10 PM Josh Price: class B;hubris;end