Functional Programming in Lean

3.7. Additional Conveniences🔗

3.7.1. Constructor Syntax for Instances🔗

내부적으로 타입 클래스는 구조체 타입이고 인스턴스는 그 타입의 값이다. 차이는 Lean이 어떤 매개변수가 출력 매개변수인지 같은 추가 정보를 타입 클래스에 저장하고 인스턴스를 검색 대상으로 등록한다는 점이다. 구조체 타입의 값은 보통 ⟨...⟩ 문법이나 중괄호와 필드로 정의하고 인스턴스는 where로 정의하지만, 두 문법 모두 두 종류의 정의에 사용할 수 있다.

예를 들어 산림 응용 프로그램은 나무를 다음과 같이 표현할 수 있다.

structure Tree : Type where latinName : String commonNames : List String def oak : Tree := "Quercus robur", ["common oak", "European oak"] def birch : Tree := { latinName := "Betula pendula", commonNames := ["silver birch", "warty birch"] } def sloe : Tree where latinName := "Prunus spinosa" commonNames := ["sloe", "blackthorn"]

세 문법은 모두 동등하다.

마찬가지로 타입 클래스 인스턴스도 세 문법 모두로 정의할 수 있다.

class Display (α : Type) where displayName : α String instance : Display Tree := Tree.latinName instance : Display Tree := { displayName := Tree.latinName } instance : Display Tree where displayName t := t.latinName

where 문법은 보통 인스턴스에 사용하고, 구조체에는 중괄호 문법이나 where 문법을 사용한다. ⟨...⟩ 문법은 구조체 타입이 필드에 이름이 붙은 튜플과 매우 비슷하다는 점을 강조하되 지금은 이름이 중요하지 않을 때 유용하다. 하지만 다른 대안을 사용하는 것이 합리적인 상황도 있다. 특히 라이브러리가 인스턴스 값을 구성하는 함수를 제공할 수 있다. 인스턴스 선언에서 := 뒤에 이 함수 호출을 두는 것이 가장 쉽다.

3.7.2. Examples🔗

Lean 코드를 실험할 때는 #eval이나 #check 명령보다 정의가 편리할 수 있다. 첫째, 정의는 출력을 만들지 않아 독자가 가장 흥미로운 출력에 집중하게 한다. 둘째, 타입 시그니처부터 시작하면 Lean이 프로그램 작성 중 더 많은 도움과 나은 오류 메시지를 제공하므로 대부분의 Lean 프로그램을 쉽게 작성할 수 있다. 반면 #eval#check는 제공된 표현식에서 Lean이 타입을 알아낼 수 있는 문맥에서 사용하기 쉽다. 셋째, 함수처럼 ToString이나 Repr 인스턴스가 없는 타입의 표현식에는 #eval을 사용할 수 없다. 마지막으로 여러 줄을 차지하는 다단계 do 블록, let 표현식 및 다른 문법 형식은 필요한 괄호를 예측하기 어려워 #eval이나 #check에서 타입 주석과 함께 작성하기 특히 어렵다.

이 문제를 피하기 위해 Lean은 소스 파일에서 예제를 명시적으로 표시하는 기능을 지원한다. 예제는 이름이 없는 정의와 같다. 예를 들어 코펜하겐 녹지에서 흔히 볼 수 있는 새의 비어 있지 않은 리스트는 다음과 같이 쓸 수 있다.

example : NonEmptyList String := { head := "Sparrow", tail := ["Duck", "Swan", "Magpie", "Eurasian coot", "Crow"] }

예제는 인수를 받아 함수를 정의할 수도 있다.

example (n : Nat) (k : Nat) : Bool := n + k == k + n

내부적으로 함수가 만들어지지만 이 함수에는 이름이 없고 호출할 수 없다. 그럼에도 주어진 타입의 임의의 값이나 미지의 값과 라이브러리를 함께 사용하는 방법을 보여 주는 데 유용하다. 소스 파일에서는 example 선언에 예제가 라이브러리 개념을 어떻게 보여 주는지 설명하는 주석을 함께 두는 것이 좋다.