I'm writing a drawing package with some parts, and I have operators and data types scattered througout. However I don't want the users to add the corresponding modules every time, since it would be quite messy, for instance I'd have a Point
class, a Monoid
role and a Style
class
in different paths like this
unit module Package::Data::Monoid;
# $?FILE = lib/Package/Data/Monoid.pm6
role Monoid {...}
unit module Package::Data::Point;
# $?FILE = lib/Package/Data/Point.pm6
class Point {...}
unit module Package::Data::Style;
# $?FILE = lib/Package/Data/Style.pm6
class Style {...}
I would like to have a haskell
like prelude in lib/Package/Prelude.pm6
with the effect that I can write such scripts
use Package::Prelude;
# I can use Point right away, Style etc...
instead of doing
use Package::Data::Style;
use Package::Data::Point;
use Package::Data::Monoid;
# I can too use point right away, but for users not knowing the
# inner workings it's too overwhelming
I've tried many things:
Package::Data::Point
...unit module Package::Prelude;
# $?FILE = lib/Package/Prelude.pm6
use Package::Data::Style;
use Package::Data::Point;
use Package::Data::Monoid;
Point
right away, but I get
problems with the operators and so on, also I would just like to
add automatically everything from the exported routines in the mentioned
example packages.# $?FILE = lib/Package/Prelude.pm6
use Package::Data::Style;
use Package::Data::Point;
use Package::Data::Monoid;
sub EXPORT {
hash <Point> => Point
, <Style> => Style
, <mappend> => &mappend
...
}
Do you people know a better and quick way of getting such a prelude-like file?
Prelude is a module that contains a small set of standard definitions and is included automatically into all Haskell modules. The documentation of prelude from GHC can be found here . If you wish to program without a prelude or to use a custom version of it you can suppress its automatic inclusion in several ways.
If you have worked on Java, then you would know how all the classes are bound into a folder called package. Similarly, Haskell can be considered as a collection of modules. Haskell is a functional language and everything is denoted as an expression, hence a Module can be called as a collection of similar or related types of functions.
In Raku module can also refer to a type of package declared with the module keyword (see Module Packages and the examples below) but here we mostly mean "module" as a set of source files in a namespace. zef is the application used for installing modules in Raku.
It is used to describe the module in the Raku ecosystem. The depends, build-depends, and test-depends sections include different modules that are used in those phases of the of installation. All are optional, but they must obviously contain the modules that are going to be needed in those particular phases.
Using EXPORT
is in the right direction. The key things to know are:
So the recipe is:
use
all the modules inside of EXPORT
EXPORT
As an example, I create a module Foo::Point
, including an operator and a class:
unit module Foo::Point;
class Point is export {
has ($.x, $.y);
}
multi infix:<+>(Point $a, Point $b) is export {
Point.new(x => $a.x + $b.x, y => $a.y + $b.y)
}
And, just to demonstrate it can work with multiple modules, also a Foo::Monad
:
unit module Foo::Monad;
class Monad is export {
method explain() { say "Just think of a burrito..." }
}
The goal is to make this work:
use Foo::Prelude;
say Point.new(x => 2, y => 4) + Point.new(x => 3, y => 5);
Monad.explain;
Which can be achieved by writing a Foo::Prelude
that contains:
sub EXPORT() {
{
use Foo::Point;
use Foo::Monad;
return ::.pairs.grep(*.key ne '$_').Map;
}
}
There's a few oddities in here to explain:
sub
has implicit declarations of $_
, $/
, and $!
. Exporting these would result in a compile-time symbol clash error when the module is use
'd. A block only has an implicit $_
. Thus we make our life easier with a nested bare block.grep
is to make sure we don't export our implicitly declared $_
symbol (thanks to the nested block, it's the only one we have to care about).::
is a way to reference the current scope (etymology: ::
is the package separator). ::.pairs
thus obtains Pair
objects for each symbol in the current scope.There's a speculated re-export mechanism that may appear in a future Raku language release that would eliminate the need for this bit of boilerplate.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With