在 raku 的模块中使用 Haskell 之类的 Prelude 模块
Use Haskell like Prelude modules in a module in raku
我正在编写一个包含某些部分的绘图包,并且我的运算符和数据类型分散在整个过程中。但是我不希望用户每次都添加相应的模块,因为这样会很乱,比如我有一个Point
class,一个Monoid
角色和一个Style
class
在这样的不同路径中
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 {...}
我想在lib/Package/Prelude.pm6
中有一个haskell
这样的前奏
效果是我可以写这样的脚本
use Package::Prelude;
# I can use Point right away, Style etc...
而不是
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
我已经尝试了很多东西:
- 这个版本没有给我正确的效果,我必须打字
指向的整个路径,即
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
,但我明白了
运营商的问题等等,我也想
自动添加上述导出例程中的所有内容
示例包。
# $?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
...
}
你们知道一个更好更快的方法来获得这样的前奏曲吗?
文件?
使用EXPORT
是正确的方向。需要了解的关键事项是:
- 导入是词法的
- 我们可以使用内省来获取和访问当前词法范围内的符号
所以食谱是:
use
EXPORT
内的所有模块
- 然后提取所有导入的符号并return它们作为
EXPORT
的结果
例如,我创建了一个模块 Foo::Point
,包括一个运算符和一个 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)
}
而且,只是为了演示它可以与多个模块一起工作,还有一个 Foo::Monad
:
unit module Foo::Monad;
class Monad is export {
method explain() { say "Just think of a burrito..." }
}
目标是完成这项工作:
use Foo::Prelude;
say Point.new(x => 2, y => 4) + Point.new(x => 3, y => 5);
Monad.explain;
这可以通过编写 Foo::Prelude
来实现,其中包含:
sub EXPORT() {
{
use Foo::Point;
use Foo::Monad;
return ::.pairs.grep(*.key ne '$_').Map;
}
}
这里有一些奇怪的地方需要解释:
- A
sub
具有 $_
、$/
和 $!
的隐式声明。当模块为 use
时,导出这些将导致编译时符号冲突错误。一个块只有一个隐含的$_
。因此,我们使用嵌套裸块让我们的生活更轻松。
grep
是为了确保我们不会导出隐式声明的 $_
符号(感谢嵌套块,这是我们唯一需要关心的)。
::
是引用当前范围的一种方式(词源:::
是包分隔符)。 ::.pairs
因此为当前范围内的每个交易品种获得 Pair
个对象。
有一种推测的再导出机制可能会出现在未来的 Raku 语言版本中,它将消除对这一点样板文件的需求。
我正在编写一个包含某些部分的绘图包,并且我的运算符和数据类型分散在整个过程中。但是我不希望用户每次都添加相应的模块,因为这样会很乱,比如我有一个Point
class,一个Monoid
角色和一个Style
class
在这样的不同路径中
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 {...}
我想在lib/Package/Prelude.pm6
中有一个haskell
这样的前奏
效果是我可以写这样的脚本
use Package::Prelude;
# I can use Point right away, Style etc...
而不是
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
我已经尝试了很多东西:
- 这个版本没有给我正确的效果,我必须打字
指向的整个路径,即
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
,但我明白了 运营商的问题等等,我也想 自动添加上述导出例程中的所有内容 示例包。
# $?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
...
}
你们知道一个更好更快的方法来获得这样的前奏曲吗? 文件?
使用EXPORT
是正确的方向。需要了解的关键事项是:
- 导入是词法的
- 我们可以使用内省来获取和访问当前词法范围内的符号
所以食谱是:
use
EXPORT
内的所有模块
- 然后提取所有导入的符号并return它们作为
EXPORT
的结果
例如,我创建了一个模块 Foo::Point
,包括一个运算符和一个 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)
}
而且,只是为了演示它可以与多个模块一起工作,还有一个 Foo::Monad
:
unit module Foo::Monad;
class Monad is export {
method explain() { say "Just think of a burrito..." }
}
目标是完成这项工作:
use Foo::Prelude;
say Point.new(x => 2, y => 4) + Point.new(x => 3, y => 5);
Monad.explain;
这可以通过编写 Foo::Prelude
来实现,其中包含:
sub EXPORT() {
{
use Foo::Point;
use Foo::Monad;
return ::.pairs.grep(*.key ne '$_').Map;
}
}
这里有一些奇怪的地方需要解释:
- A
sub
具有$_
、$/
和$!
的隐式声明。当模块为use
时,导出这些将导致编译时符号冲突错误。一个块只有一个隐含的$_
。因此,我们使用嵌套裸块让我们的生活更轻松。 grep
是为了确保我们不会导出隐式声明的$_
符号(感谢嵌套块,这是我们唯一需要关心的)。::
是引用当前范围的一种方式(词源:::
是包分隔符)。::.pairs
因此为当前范围内的每个交易品种获得Pair
个对象。
有一种推测的再导出机制可能会出现在未来的 Raku 语言版本中,它将消除对这一点样板文件的需求。