Мне нужно реализовать общий стек для чего-то, над чем я работаю. Этот стек должен содержать элементы разных типов. Например, (1, 'c', True, "Strings"). Поддерживаемые функции: верх, поп и толчок.Общая информация «typeless» STack in Haskell
Кортежи - самая естественная идея для этого.
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)
Здесь, сверху дает мне ошибку:
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
Может кто-нибудь помочь мне с подписями правильного типа или определения типа для такого стека ? Или, может быть, назовите меня хорошей ссылкой, связанной с этим?
Большое спасибо за продвинутый!
Edit:
Было бы идеально, если я был бы в состоянии включить функцию ПОЛУЧИТЬ для этого стека. Учитывая целое число i и стек s, get будет возвращать i-й элемент s. Я надеялся, что, возможно, я смогу сделать это сам, как только толчок, поп и верх будут отсортированы, но я все еще не могу. Любые идеи относительно этих парней?
спасибо! это довольно удивительная реализация! –
Было бы прекрасно, если бы я мог включить функцию get для этого стека. Учитывая целое число i и стек s, get будет возвращать i-й элемент s. Я надеялся, что, возможно, я смогу сделать это сам, как только толчок, поп и верх будут отсортированы, но я все еще не могу. Есть идеи по этому поводу? –
@ shivanker.goel Это то, что очень сложно с этой реализацией. Это не так уж плохо, если индекс определяется только во время компиляции, но это невероятно сложно, если индекс может быть выбран во время выполнения. В этот момент это становится практически неработоспособным в Haskell. – Carl