Skip to main content

Bài 7: Marlowe nhúng trong Haskell

Trong hướng dẫn này, chúng ta quay lại ví dụ ký quỹ và chỉ ra cách chúng ta có thể sử dụng việc nhúng Marlowe vào Haskell để tạo ra các mô tả dễ đọc hơn, mô-đun và có thể tái sử dụng về các hợp đồng Marlowe.

Một hợp đồng ký quỹ đơn giản.

Picture

Nhớ lại rằng chúng ta đã phát triển hợp đồng Marlowe này trong hướng dẫn trước đó của chúng ta.

Mặc dù chúng ta đã trình bày nó ở đó như một hợp đồng “monolothic”, chúng ta có thể sử dụng các định nghĩa của Haskell để làm cho nó dễ đọc hơn. Để bắt đầu, chúng ta có thể tách cam kết ban đầu khỏi phần làm việc bên trong của hợp đồng:

contract :: Contract
contract = When [Case (Deposit "alice" "alice" ada price) inner]
10
Close

inner :: Contract
inner =
When [ Case aliceChoice
(When [ Case bobChoice
(If (aliceChosen ValueEQ bobChosen)
agreement
arbitrate) ]
60
arbitrate)
]
40
Close

Nhiều thuật ngữ ở đây được tự định nghĩa trong Haskell. Về cơ bản, chúng ta có hai hợp đồng giải quyết những gì xảy ra khi có agreementgiữa Alice và Bob, và nếu không, Carol nên làm thế nào arbitrategiữa họ:

agreement :: Contract
agreement =
If
(aliceChosen ValueEQ (Constant 0))
(Pay "alice" (Party "bob") ada price Close)
Close

arbitrate :: Contract
arbitrate =
When [ Case carolClose Close,
Case carolPay (Pay "alice" (Party "bob") ada price Close) ]
100
Close

Trong các hợp đồng này, chúng ta cũng sử dụng các từ viết tắt đơn giản như:

price :: Value
price = Constant 450

Cho biết giá của con mèo và giá trị của số tiền được ký quỹ.

Chúng ta cũng có thể mô tả các lựa chọn của Alice và Bob, lưu ý rằng chúng ta cũng được yêu cầu cung cấp một giá trị mặc định defValue đề phòng trường hợp các lựa chọn chưa được thực hiện.

aliceChosen, bobChosen :: Value

aliceChosen = ChoiceValue (ChoiceId choiceName "alice")
bobChosen = ChoiceValue (ChoiceId choiceName "bob")

defValue = Constant 42

choiceName :: ChoiceName
choiceName = "choice"

Khi mô tả các lựa chọn, chúng ta có thể đặt tên hợp lý cho các giá trị số:

pay,refund,both :: [Bound]

pay = [Bound 0 0]
refund = [Bound 1 1]
both = [Bound 0 1]

và xác định các Hàm mới (hoặc "mẫu") cho chính chúng ta. Trong trường hợp này, chúng ta xác định

choice :: Party -> [Bound] -> Action

choice party bounds =
Choice (ChoiceId choiceName party) bounds

như một cách làm cho việc diễn đạt các lựa chọn trở nên đơn giản hơn và dễ đọc hơn:

alicePay, aliceRefund, aliceChoice :: Action
alicePay = choice "alice" pay
aliceRefund = choice "alice" refund
aliceChoice = choice "alice" both

Với tất cả các định nghĩa này, chúng ta có thể viết hợp đồng ở đầu phần này theo cách làm rõ ý định của nó. Viết bằng Marlowe thuần khiết, hoặc bằng cách mở rộng các định nghĩa này, chúng ta sẽ có hợp đồng này thay thế:

Mã code mẫu
When [
(Case
(Deposit
"alice" "alice" ada
(Constant 450))
(When [
(Case
(Choice
(ChoiceId "choice" "alice") [
(Bound 0 1)])
(When [
(Case
(Choice
(ChoiceId "choice" "bob") [
(Bound 0 1)])
(If
(ValueEQ
(ChoiceValue
(ChoiceId "choice" "alice"))
(ChoiceValue
(ChoiceId "choice" "bob")))
(If
(ValueEQ
(ChoiceValue
(ChoiceId "choice" "alice"))
(Constant 0))
(Pay
"alice"
(Party "bob") ada
(Constant 450) Close) Close)
(When [
(Case
(Choice
(ChoiceId "choice" "carol") [
(Bound 1 1)]) Close)
,
(Case
(Choice
(ChoiceId "choice" "carol") [
(Bound 0 0)])
(Pay
"alice"
(Party "bob") ada
(Constant 450) Close))] 100 Close)))] 60
(When [
(Case
(Choice
(ChoiceId "choice" "carol") [
(Bound 1 1)]) Close)
,
(Case
(Choice
(ChoiceId "choice" "carol") [
(Bound 0 0)])
(Pay
"alice"
(Party "bob") ada
(Constant 450) Close))] 100 Close)))
]
Bài tập
  • Bạn có thể thêm những từ viết tắt nào khác vào hợp đồng ở đầu trang?
  • Bạn có thể phát hiện ra bất kỳ Hàm nào mà bạn có thể xác định để làm cho hợp đồng ngắn hơn hoặc theo mô-đun hơn không?

Ví dụ này đã cho thấy cách nhúng trong Haskell mang lại cho chúng ta một ngôn ngữ biểu đạt hơn, chỉ đơn giản bằng cách sử dụng lại một số tính năng cơ bản của Haskell, cụ thể là các định nghĩa về hằng số và hàm. Trong hướng dẫn tiếp theo, bạn sẽ tìm hiểu về cách xác định hợp đồng bằng cách sử dụng JavaScript nhúng.

Ghi chú

Bạn có thể tìm thấy một số ví dụ khác về việc sử dụng Haskell để xây dựng hợp đồng Marlowe trong Marlowe Playground, nơi cũng có thể xây dựng các hợp đồng Marlowe được nhúng Haskell.

  • Picture