문제
Haskell의 다음 설계 문제를 고려하십시오. 변수 및 일반 표현식 (다변량 다항식)을 표현하려는 단순하고 상징적 인 EDSL이 x^2 * y + 2*z + 1
있습니다. 또한, 나는 표정, 말을 통해 특정 기호 방정식을 표현 할 x^2 + 1 = 1
뿐만 아니라 정의 처럼 x := 2*y - 2
.
목표는 다음과 같습니다.
- 변수와 일반 표현식에 대해 별도의 유형이 있어야합니다. 특정 함수는 복잡한 표현식이 아니라 변수에 적용될 수 있습니다. 예를 들어, 정의 연산자
:=
는 유형일 수 있으며(:=) :: Variable -> Expression -> Definition
복잡한 표현식을 왼쪽 매개 변수로 전달할 수 없어야 합니다 ( 명시 적 캐스트없이 변수를 오른쪽 매개 변수로 전달할 수 있어야 함 ) . Num
정수 리터럴을 표현식으로 승격하고 보조 래퍼 연산자를 도입하지 않고 덧셈 또는 곱셈과 같은 일반적인 대수 연산에 편리한 표기법을 사용할 수 있도록 표현식에의 인스턴스를 사용하십시오.
즉, 변수에 대한 암시 적 및 정적 유형 캐스트 (강제)를 표현식에 사용하려고합니다. 이제 Haskell에는 암시 적 유형 캐스트가 없다는 것을 알고 있습니다. 그럼에도 불구하고 특정 객체 지향 프로그래밍 개념 (이 경우 간단한 상속)은 언어 확장 유무에 관계없이 하스켈 유형 시스템에서 표현할 수 있습니다. 간단한 구문을 유지하면서 어떻게 위의 두 가지 사항을 모두 만족시킬 수 있습니까? 가능합니까?
토론
여기서 주요 문제는 Num
유형 제한입니다.
(+) :: Num a => a -> a -> a
원칙적으로 변수와 표현식 모두에 대해 단일 (일반화 된) 대수 데이터 유형을 작성할 수 있습니다. 그런 다음 :=
왼쪽 식을 식별하고 변수 생성자 만 허용하고 그렇지 않으면 런타임 오류가 발생하는 방식으로 작성할 수 있습니다. 그러나 그것은 깨끗하고 정적 인 (즉 컴파일 타임) 솔루션이 아닙니다 ...
예
이상적으로는 다음과 같은 간단한 구문을 얻고 싶습니다.
computation = do
x <- variable
t <- variable
t |:=| x^2 - 1
solve (t |==| 0)
특히, 전체 왼쪽 표현이 아닌 변수의 정의를 제공해야 t + 1 |:=| x^2 - 1
하므로 표기법을 금지하고 싶습니다
:=
.
FromVar
typeclass가 어떻게 도움이 될지 잘 모르겠습니다 . Expr
의 인스턴스 를 유지하면서 명시 적 캐스트를 피하고 싶습니다 Num
. 달성하고자하는 표기법의 예를 추가하여 질문을 편집했습니다.
class FromVar e
메소드fromVar :: Variable -> e
와 함께 and를 사용할 수Expression
있고Variable
, 변수에 다형성 유형x :: FromVar e => e
등 을 가질 수 있습니다 . 나는 지금 휴대 전화를 사용하고 있기 때문에 이것이 얼마나 잘 작동하는지 테스트하지 않았습니다.