Daml for Haskellers: interview with Heitor Toledo Lassarote de Paula

Daml is often approachable to Haskell developers because it shares many familiar language-level features: algebraic data types, parametric polymorphism, higher-order functions, immutable values, and an explicit effect type in the form of Update. These similarities, however, can obscure the fact that Daml programs execute within a fundamentally different semantic model.

A Daml application does not operate on an ordinary mutable database. It defines templates whose instances are contracts on a ledger, together with choices that describe the permitted transitions between contractual states. Contract creation, exercise, archival, authorization, and disclosure are validated as part of an atomic transaction. If any step fails, the entire transaction is rolled back.

This execution model introduces concerns that are largely external to the type system. Developers must reason about signatories, observers, controllers, contract-key maintainers, transaction witnesses, and divulgence. A choice may be well typed while still failing at runtime because the submitting parties do not provide the required authorization. Likewise, a transaction may be functionally correct while disclosing data to parties that were not expected to see it.

The resulting design style differs from both conventional backend development and Ethereum-style smart contracts. State transitions are modeled through the exercise of contractual rights rather than arbitrary mutation, and access control is expressed through the ledger model rather than implemented solely through application-level checks.

In this interview with our Daml Team Lead, Heitor, we examine which Haskell intuitions transfer successfully to Daml, where analogies such as Update and IO break down, and how developers should reason about authorization, visibility, contract lifecycles, and testing. We also discuss learning paths and tooling for Daml developers, common mistakes made by Solidity programmers, and the practical topics covered in the upcoming Daml Smart Contracts Development Guide. a5tjt96.heitor.jpg

Daml’s syntax and type system feel familiar to Haskell developers, but its execution model is very different. Which Haskell intuitions remain useful when learning Daml, and which ones can become misleading when working with contracts, parties, and ledger transactions?

The main potentially misleading point to keep in mind is that the Update type, the closest analogue to Haskell’s IO, has an important distinguishing feature: it is atomic. In Haskell, if you perform two IO actions and the second fails, the first may already have taken effect and could be irreversible. By contrast, a Daml Update will roll back all ledger changes if any intermediate action fails.

Another important area is the authorization system. Haskell developers are accustomed to expressing invariants through types. Although Daml’s type checker verifies that a controller expression is well typed, whether a participant is actually authorized to exercise a choice is checked at runtime.

As for useful intuitions, Haskell developers are already familiar with immutability, and the Canton ledger can be understood as a set of immutable smart contracts. Updating a contract means archiving it and creating a new one, somewhat like Haskell’s record-update semantics.

In Haskell, side effects are made explicit through types such as IO, while in Daml contract creation, exercise, authorization, and visibility are governed by the ledger model. How would you explain this difference to a Haskell developer encountering Daml for the first time?

As in Haskell, Daml makes side effects explicit through a type: Update, which indicates that a function may perform actions on the ledger. Every choice implicitly returns a value wrapped in this type.

However, one thing that makes it different to Haskell is Daml’s authorization model. Daml developers must specify in advance which parties are allowed to exercise an action. Every choice—roughly analogous to a method on a smart contract—has a controller expression indicating who may exercise it. Intermediate actions may require additional authorization as well. Developers must think ahead of all of this and test thoroughly to ensure that all authorization requirements are satisfied. Contracts also have signatories, whose authorization is required for their creation and archival, and this must be taken into account when designing workflows.

Another important consideration is visibility. If a third party participates in a transaction, it may gain visibility into a contract, either as a witness to its creation or through divulgence when an existing contract is fetched or exercised as part of the transaction. A Daml developer must ensure that data is disclosed only to the intended parties. Because these visibility properties are not enforced by the type system, developers must test carefully to confirm that the implementation matches their privacy expectations.

What learning path would you recommend for an experienced Haskell, Scala, or backend developer who wants to become productive with Daml, and which topics, tools, and hands-on exercises should they prioritize first?

Because damlc, the Daml compiler, is derived from GHC and Daml itself is derived from Haskell, prior Haskell experience already covers much of the language’s syntax and functional programming model. Scala developers should likewise have little trouble getting familiarized with its functional concepts.

I would recommend starting with the Daml certification learning paths, which are where I first learned the language. The existing courses were created for Daml 2, but work is underway to modernize them for Daml 3.

That said, as mentioned in my previous answers, the greatest challenge in learning Daml is understanding the ledger model, particularly authorization and visibility. These are therefore the two most important topics to get familiarized with.

As for tooling, the Daml ecosystem continues to evolve. Daml Studio is currently the recommended IDE experience, although, in my experience, Neovim users may also enjoy daml.nvim. The toolchain is managed through DPM.

For hands-on practice, it is important not only to read articles but also to begin writing Daml tests early, covering both successful and unsuccessful scenarios. Developers should inspect the table and transaction views provided by the Script Results code lenses. Even rewriting examples from a tutorial, rather than simply copying and pasting them, is a valuable exercise.

A Haskell developer may be able to read Daml code almost immediately, but writing secure and privacy-preserving Daml applications requires more than understanding the syntax. What are the most important ledger-specific principles that Haskellers need to learn before working on production systems?

As mentioned earlier, authorization and visibility are among Canton’s defining features, and Daml developers must become comfortable reasoning about both.

To do so, developers should test early and often. A disciplined approach that includes both positive and negative tests should be used not only as a learning tool but also as a systematic part of maintaining production code. The type system will not catch every authorization or visibility mistake.

Developers should also design stakeholder roles carefully. Signatories, observers, controllers, and maintainers must be assigned thoughtfully. Doing so helps prevent unintended witnessing or divulgence, ensures that the appropriate contract-key maintainers can authorize lookups, and avoids contract-key collisions, among other authorization and visibility issues.

Let’s discuss what readers can expect from the Daml Smart Contracts Guide you’re currently working on. What level of knowledge should a developer have to use this guide effectively, who is it primarily intended for, and what topics and practical skills will it cover?

Readers are expected to have some familiarity with blockchain development, and the guide assumes basic knowledge of Solidity. Haskell experience is not required, although it is highly beneficial for developers who intend to work extensively with Daml. The article links to several Haskell tutorials, while the Daml courses mentioned earlier also include a Haskell crash course.

The guide is intended both for developers looking for a quick introduction to Daml and Canton and for technical managers who want to understand the benefits they can bring to a project and why a team might choose to build on Canton.

The article provides an overview of Canton and Daml and compares them with Ethereum and Solidity. By the end, readers will have written their first smart contract in Daml, along with tests for it, giving them an initial understanding of how to design smart contracts with data sovereignty in mind.

Finally, the article explains how to deploy the application to a local Canton sandbox and interact with it through Daml Script.

You compare Daml with Solidity throughout the upcoming guide, particularly their approaches to state, authorization, and privacy. Which habits from Ethereum or Solidity development are most likely to lead developers toward incorrect or unnecessarily complicated Daml architectures?

Solidity encourages developers to mutate state in place, whereas Daml embraces an archive-and-recreate model. For example, Solidity developers might use a mapping such as mapping(address => uint) to represent each user’s balance. This design does not translate naturally to Daml, where each user might instead have a separate contract containing an immutable balance.

Another common Solidity habit is implementing owner-style authorization checks inside contract methods. On Ethereum, this is typically done using require assertions. Daml instead encourages developers to express authorization through signatories, observers, and controllers, with the ledger enforcing these rules rather than the contract logic alone. Although Daml developers can still perform runtime assertions related to authorization, this is generally not the most idiomatic approach. Solidity developers therefore need to adopt a different perspective on authorization and visibility and plan both more deliberately.

Data visibility is another important difference. On Ethereum, data is public by default, and anyone with an address can read the associated state. In Daml, operations such as fetchByKey are subject to visibility and authorization rules; not every party is permitted to perform a lookup.

Contract identifiers also require a different approach. Because contracts are archived and recreated in Daml, holding on to a contract ID—the closest analogue to an address—is not sufficient. Each newly created contract receives a new ID, so developers will often need to locate the current contract again, for example by using its contract key.

The upcoming Daml guide highlights that Daml contracts represent rights and obligations rather than mutable objects. How does this perspective change the way developers should think about updates, cancellations, and state transitions in comparison with conventional backend development?

In conventional backend development, state is often modeled as data that an application may mutate whenever its business logic permits. In Daml, a contract instead represents a specific set of rights and obligations held by particular parties. A state transition is therefore not merely a change to stored data; it is the exercise of a right by an authorized party, with the resulting transaction establishing a new legal or business state.

This perspective makes authorization part of the domain model rather than an external access-control layer. Choices describe which actions are available, who may exercise them, and what consequences follow. The ledger then verifies that the required parties have authorized the transaction before committing it.

The Propose–Accept pattern is a common example. One party proposes an arrangement, while another explicitly accepts or rejects it. Until it is accepted, the proposal does not impose the same obligations as the final agreement. Cancellations should be modeled in the same way: not as arbitrary deletion, but as a choice available to a party that holds the contractual right to terminate the arrangement. Thinking in terms of rights, consent, and obligations leads to models that more closely reflect the underlying business process.

Daml for Haskellers: interview with Heitor Toledo Lassarote de Paula
Banner that links to Serokell Shop. You can buy cool FP T-shirts there!
More from Serokell
daml interview:  a Haskell-based language for blockchaindaml interview:  a Haskell-based language for blockchain
Rust vs. Haskell thumbnailRust vs. Haskell thumbnail
haskell in production standard chartered thumbnailhaskell in production standard chartered thumbnail