Мне нужно реализовать общий стек для того, над чем я работаю. Этот стек должен содержать элементы разных типов. Например, (1, 'c', True, "Strings"). Поддерживаемые функции: top, pop и push.
Кортежи - самая естественная идея для этого.
push x s = (x,s)
pop s = snd s
top s = (fst s, s)
Но мне также нужно поддерживать пустой стек. Здесь pop и top не определены в (). Поэтому я попытался создать новый тип.
data Stack = Empty | forall x. Cons (x, Stack)
push x s = Cons (x,s)
pop s = case s of
Empty -> Left s
Cons (x, y) -> Right y
top s = case s of
Empty -> (Left (), s)
Cons (x,y) -> (Right x, s)
Здесь top дает мне ошибку:
Couldn't match expected type ‘b’ with actual type ‘x’
because type variable ‘x’ would escape its scope
This (rigid, skolem) type variable is bound by
a pattern with constructor
Cons :: forall x. (x, Stack) -> Stack,
in a case alternative
at try.hs:11:9-18
Relevant bindings include
x :: x (bound at try.hs:11:15)
top :: Stack -> (Either () b, Stack) (bound at try.hs:9:1)
In the first argument of ‘Right’, namely ‘x’
In the expression: Right x
Если я обойду это с помощью:
data Stack x = Empty | forall y. Cons (x, Stack y)
Я получаю ту же ошибку для поп.
Я также попытался добавить это:
type AnyStack = forall x. Stack x
но снова получаю аналогичную ошибку:
Couldn't match expected type ‘b’ with actual type ‘Stack y’
because type variable ‘y’ would escape its scope
This (rigid, skolem) type variable is bound by
a pattern with constructor
Cons :: forall x y. (x, Stack y) -> Stack x,
in a case alternative
at try.hs:8:9-19
Relevant bindings include
y :: Stack y (bound at try.hs:8:18)
pop :: Stack t -> Either (Stack t) b (bound at try.hs:6:1)
In the first argument of ‘Right’, namely ‘y’
In the expression: Right y
Может ли кто-нибудь помочь мне с правильными сигнатурами или определением типа для такого стека? Или, может быть, укажите мне на какую-нибудь хорошую ссылку, связанную с этим?
Заранее большое спасибо!
Изменить:
Было бы идеально, если бы я также мог включить функцию получения для этого стека. Учитывая целое число i и стек s, get вернет i-й элемент s. Я надеялся, что, вероятно, смогу сделать это сам, как только разберусь с толканием, поп и верхом, но я все еще не могу. Любые идеи относительно этих ребят?