raku의 모듈에서 Haskell을 Prelude 모듈처럼 사용하십시오.


11

일부 부품으로 도면 패키지를 작성하고 있으며 연산자와 데이터 유형이 흩어져 있습니다. 그러나 사용자가 매번 해당 모듈을 추가하는 것을 원하지 않습니다. 예를 들어, Point클래스, Monoid역할 및 Style클래스가 다른 경로에 있기 때문에 상당히 지저분 합니다.

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

당신은 사람들이 그런 전주곡 같은 파일을 얻는 더 좋고 빠른 방법을 알고 있습니까?


사용할 수 있습니다 unit class Package::Data::Point. 을 사용할 필요는 없습니다 module.
브래드 길버트

답변:


12

사용 EXPORT은 올바른 방향입니다. 알아야 할 주요 사항은 다음과 같습니다.

  • 수입은 어휘
  • 내부 어휘를 사용하여 현재 어휘 범위의 기호를 얻고 액세스 할 수 있습니다

레시피는 다음과 같습니다.

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

여기에 설명 할 몇 가지 이상한 점이 있습니다.

  1. A는 sub암시 적 선언을 가지고 $_, $/하고 $!. 이를 내 보내면 모듈이 use'd 일 때 컴파일 타임 심볼 충돌 오류가 발생합니다 . 블록에는 암시 적 만 있습니다 $_. 따라서 우리는 중첩 된 베어 블록으로 우리의 삶을 더 쉽게 만듭니다.
  2. 이것은 grep우리가 암시 적으로 선언 한 $_심볼을 내 보내지 않도록하는 것 입니다.
  3. ::현재 범위를 참조하는 방법입니다 (용어 : ::패키지 구분 기호입니다). ::.pairs따라서 Pair현재 범위의 각 심볼에 대한 객체를 얻습니다 .

향후 라쿠 언어 릴리스에 나타날 수있는 추측 된 재수출 메커니즘이 있습니다.


마지막으로, 이것은 내가 찾던 행동입니다. 정말 고마워요!
margolari
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.