네임 스페이스는 이름과 클래스 클래스는 이름으로 구성 목록과 방법은 이름, 반환 형식 및 인수의 목록으로 구성 방법의 목록으로 구성이 인수 유형으로 구성되어 있으며 이 간단한 언어로 프로그램의 이름 예 :
당신은 또한 당신의 타입 시스템에 대한 유형 정의가 필요하고 실제로 조합 유형이 가치가있는 유일한 장소입니다
:
type Type = Void | Int | String
언어의 유형은 int 또는 문자열 또는 void이지만 아무 것도 사용할 수 없습니다 (예 : null), 그러한 옵션은 복수 일 수 없습니다.
네임 스페이스의 유형은 다음과 같이 완전히 익명 수 :
string * (string * (Type * string * (Type * string) list) list) list
는이처럼 예 네임 스페이스를 정의 할 수 있습니다 :
실제로
"ns", ["cls1", [Void, "m1", []]
"cls2", [Void, "m2", [Int, "i"; String, "j"]]]
, 당신은 아마 넣을 수있는 기능을 원하는 다른 네임 스페이스에 네임 스페이스를 추가하고 클래스를 클래스에 추가하여 코드를 다음과 같이 변형 할 수 있습니다.
type Type =
| Void
| Int
| String
| Class of Map<string, Type> * Map<string, Type * (Type * string) list>
type Namespace =
| Namespace of string * Namespace list * Map<string, Type>
Namespace("ns", [],
Map
[ "cls1", Class(Map[], Map["m1", (Void, [])])
"cls2", Class(Map[], Map["m2", (Void, [Int, "i"; String, "j"])])])
익명 유형은 혼란의 원인이되지 않는 한 괜찮습니다. 엄지 손가락의 규칙에 따라 두 개 또는 세 개의 필드가 있고 서로 다른 유형 (예 : "메서드") 인 경우 튜플이 좋습니다. 동일한 유형의 필드가 더 많거나 여러 필드가있는 경우 레코드 유형으로 전환해야합니다.
그래서이 경우 당신은 방법에 대한 레코드 유형을 소개 할 수 있습니다 :
type Method =
{ ReturnType: Type
Arguments: (Type * string) list }
and Type =
| Void
| Int
| String
| Class of Map<string, Type> * Map<string, Method>
type Namespace =
| Namespace of string * Namespace list * Map<string, Type>
Namespace("ns", [],
Map
[ "cls1", Class(Map[], Map["m1", { ReturnType = Void; Arguments = [] }])
"cls2", Class(Map[], Map["m2", { ReturnType = Void; Arguments = [Int, "i"; String, "j"] }])])
어쩌면 도우미 함수를 레코드 구성하기 :
let Method retTy name args =
name, { ReturnType = retTy; Arguments = args }
Namespace("ns", [],
Map
[ "cls1", Class(Map[], Map[Method Void "m1" []])
"cls2", Class(Map[], Map[Method Void "m2" [Int, "i"; String, "j"]])])
흠을 모두 너무 혼합, 나는 그것을 기대하고 있었다. –
나는 단지 튜플로 DU를 사용하는 경향이있다. 작성하기가 쉽지만 인수가 두 가지 이상인 곳에서는 혼란 스러울 수 있습니다. 설명서의 내용에 따라 각각 무엇인지 알려줍니다. 예를 들어, Method의 Parameters의 경우,'Parameters : (String * TypeName) list option' 옵션을 대신 사용할 수 있습니다. 튜플의 각 항목이 나타내는 것은 분명합니다. 그러나 TypeName이 아닌 Type에도 String을 사용하고'(String * String)'을 사용했다면 각각의 목적을 이해할 수있는 레코드가 필요합니다. –
나는 가독성 측면에서 일반적으로 오류를 일으키므로 투플 대신 레코드를 사용한다. –