I'm a bit struggling with creating an interface for a "generic Stack" (regardless of whether it already exists in a package or not, I'm trying to create my own for educational purposes)
If I have the two expect
at the bottom uncommented at the same time, roc check
stops being my friend.
And if I have one of the expect
uncommented, and I add the type signature to empty
(I think the type would be empty : Stack *
, then roc check also stops being my friend.
interface Stack
exposes [
Stack,
empty,
withCapacity,
isEmpty,
top,
put,
pop,
]
imports []
Stack a := List a
# 👇 If I uncoment this type annotation (together with one of the tests below), then roc check is no longer happy
#empty : Stack *
empty = fromList []
fromList : List a -> Stack a
fromList = \list -> @Stack list
withCapacity : Nat -> Stack a
withCapacity = \elements ->
@Stack (List.withCapacity elements)
isEmpty : Stack * -> Bool
isEmpty = \@Stack stack ->
stack |> List.isEmpty
top : Stack a -> Result a [StackWasEmpty]
top = \@Stack stack ->
stack |> List.last |> Result.mapErr (\_ -> StackWasEmpty)
put : Stack a, a -> Stack a
put = \@Stack stack, elem ->
@Stack (stack |> List.append elem)
pop : Stack a -> Result { elem : a, stack : Stack a } [StackWasEmpty]
pop = \@Stack stack ->
when (stack |> List.last) is
Ok elem -> Ok { elem, stack: @Stack (stack |> List.dropLast) }
Err ListWasEmpty -> Err StackWasEmpty
expect (empty |> isEmpty) == Bool.true
## 👇 I can't have these two uncommented at the same time 😖
expect (empty |> put 1 |> put 2 |> pop |> Result.map .elem) == Ok 2
#expect (empty |> put "A" |> put "B" |> pop |> Result.map .elem) == Ok "B"
This is the nightly version of roc. Am I doing something impossible, or is this a well-known issue?
Empty needs to be a function
Then it would be used as empty {}
To create a new empty stack
Yeah, I'm looking at Dict, and indeed, Dict.empty is also used as Dict.empty {}
Ok, let me make some adjustments :D :sweat_smile:
:tada: As a wise man used to say, "There's nothing like speaking with those who know". Thanks @Brendan Hansknecht that was the solution :pray::pray:
Fábio Beirão has marked this topic as resolved.
@Ayaz Hafiz do you think there is a way for the compiler to give a better error message related to this and #ideas > Let-generalization - let's not? ? Should we file an issue for clarity in the error message here or would that not really be possible?
yeah, we should definitely give better error messages. There's a section in the "Let's not?" doc that describes how we can do it, so that can be referenced in the issue
Can you write up the issue since you have more context?
sure, will do
Last updated: Jul 06 2025 at 12:14 UTC