gpt4 book ai didi

haskell - 在 raku 的模块中使用 Haskell 之类的 Prelude 模块

转载 作者:行者123 更新时间:2023-12-02 01:44:47 25 4
gpt4 key购买 nike

我正在编写一个包含一些部分的绘图包,并且我的运算符和数据类型分散在各处。但是我不希望用户每次都添加相应的模块,因为它会很困惑,例如我会有一个 Point类,一个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 {...}

我想要一个 haskell就像 lib/Package/Prelude.pm6 中的前奏
大意是我可以写这样的脚本

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是在正确的方向。需要了解的关键事项是:

  • 导入是词法
  • 我们可以使用自省(introspection)来获取和访问当前词法范围内的符号

  • 所以配方是:
  • use EXPORT 中的所有模块
  • 然后提取所有导入的符号并将它们作为 EXPORT 的结果返回

  • 例如,我创建了一个模块 Foo::Point ,包括一个运算符和一个类:

    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;
    }
    }

    这里有一些奇怪的地方需要解释:
  • 一个 sub隐含声明 $_ , $/ , 和 $! .当模块为 use 时,导出这些将导致编译时符号冲突错误。 'd。一个 block 只有一个隐含的 $_ .因此,我们使用嵌套的裸 block 使我们的生活更轻松。
  • grep是确保我们不会导出隐式声明的 $_符号(感谢嵌套 block ,这是我们唯一需要关心的)。
  • ::是引用当前范围的一种方式(词源::: 是包分隔符)。 ::.pairs从而得到Pair当前范围内每个符号的对象。

  • 有一种推测的再导出机制可能会出现在 future 的 Raku 语言版本中,这将消除对这一样板文件的需求。

    关于haskell - 在 raku 的模块中使用 Haskell 之类的 Prelude 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61179586/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com