[英]Type troubles with custom typeclass
I'm having some trouble with types while learning Haskell. 我在学习Haskell时遇到类型问题。 I have a typeclass called
Stack
which obviously should behave like a stack. 我有一个称为
Stack
的类型类,显然应该表现得像一个堆栈。 I have a type Elem
which is simply either an Int or a Bool. 我有一个
Elem
类型,它只是一个Int或Bool。
Now I want my function to take a Stack
of Elem
and do some operations with it. 现在,我想我的功能采取
Stack
的Elem
,并做一些操作它。 The result is not actually important, however I am failing to even acquire the first element of the stack and I have failed to figure out what is wrong for hours now. 结果实际上并不重要,但是我什至没有获得堆栈的第一个元素,而且现在几个小时都没弄清什么地方出了问题。
import Control.Monad
data Elem = Number Int | Truth Bool deriving Eq
instance Show Elem where
show (Number i) = show i
show (Truth b) = show b
class Stack stack where
push :: a -> stack a -> stack a
top :: MonadPlus m => stack a -> m (a,stack a)
empty :: stack a
isEmpty :: stack a -> Bool
instance Stack [] where
push a stack = a:stack
top stack = if isEmpty stack then mzero else return (head stack, tail stack)
empty = []
isEmpty stack = if null stack then True else False
step :: Stack stack => String -> stack Elem -> Maybe (stack Elem)
step ex st = let e1 = top st :: Maybe (Elem, stack Elem)
--a1 = fmap fst e1
--e2 = top (fmap snd e1)
--a2 = fmap fst e2
in Nothing
The error I am getting is 我得到的错误是
Playground.hs:22:27:
Could not deduce (stack ~ stack2)
from the context (Stack stack)
bound by the type signature for
step :: Stack stack => String -> stack Elem -> Maybe (stack Ele
m)
at Playground.hs:21:9-65
`stack' is a rigid type variable bound by
the type signature for
step :: Stack stack => String -> stack Elem -> Maybe (stack Elem
)
at Playground.hs:21:9
`stack2' is a rigid type variable bound by
an expression type signature: Maybe (Elem, stack2 Elem)
at Playground.hs:22:23
Expected type: stack2 Elem
Actual type: stack Elem
Relevant bindings include
st :: stack Elem
(bound at Playground.hs:22:9)
step :: String -> stack Elem -> Maybe (stack Elem)
(bound at Playground.hs:22:1)
In the first argument of `top', namely `st'
In the expression: top st :: Maybe (Elem, stack Elem)
I really fail to see why Haskell refuses this (and even refuses simply calling top st
in my function without me trying to specify a type). 我真的不明白为什么Haskell会拒绝此操作(甚至拒绝在我不尝试指定类型的情况下在函数中直接调用
top st
)。
I hope someone can shed some light on this! 我希望有人能对此有所启发!
As two commenters suggested, you need -XScopedTypeVariables
. 正如两个评论者所建议的那样,您需要
-XScopedTypeVariables
。
The following code compiles for me: 以下代码为我编译:
{-# LANGUAGE ScopedTypeVariables #-}
module Foo where
import Control.Monad
data Elem = Number Int | Truth Bool deriving Eq
instance Show Elem where
show (Number i) = show i
show (Truth b) = show b
class Stack stack where
push :: a -> stack a -> stack a
top :: MonadPlus m => stack a -> m (a,stack a)
empty :: stack a
isEmpty :: stack a -> Bool
instance Stack [] where
push a stack = a:stack
top stack = if isEmpty stack then mzero else return (head stack, tail stack)
empty = []
isEmpty stack = if null stack then True else False
step :: forall stack . Stack stack => String -> stack Elem -> Maybe (stack Elem)
step ex st = let e1 = top st :: Maybe (Elem, stack Elem)
--a1 = fmap fst e1
--e2 = top (fmap snd e1)
--a2 = fmap fst e2
in Nothing
I'm not sure what you mean about "not having access to the forall
syntax", but if you really want to avoid it, you can also write step
like this: 我不确定“无法访问
forall
语法”的含义,但是如果您真的想避免这种情况,也可以编写如下step
:
step :: Stack stack => String -> stack Elem -> Maybe (stack Elem)
step ex (st :: stack Elem) = let e1 = top st :: Maybe (Elem, stack Elem)
--a1 = fmap fst e1
--e2 = top (fmap snd e1)
--a2 = fmap fst e2
in Nothing
You'll still need ScopedTypeVariables
though. 但是,您仍然需要
ScopedTypeVariables
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.