【问题标题】:runtime error: No instance for (Stacked Int) arising from a use of ‘/+/’运行时错误:没有因使用“/+/”而导致 (Stacked Int) 的实例
【发布时间】:2020-07-30 11:59:40
【问题描述】:

我写了一个简单的类型:Stack 和一个类类型Stacked,带有两个操作“加号”和“减号”的实例。它已编译但运行时会产生标题上的错误。 代码是:

newtype Stack a = Stack a deriving (Show)

class Stacked a  where 
    (/+/) :: a -> Stack [a] -> Stack [a]
    (/-/) :: Stack [a] -> Stack [a]

instance Stacked (Stack a) where
    (/+/) x (Stack xs) = Stack (x:xs) 
    (/-/) (Stack xs) = Stack (tail xs)

我尝试在实例中使用 (Stacked a) => ...,但没有结果。 我做错了什么?

附言。我知道我必须检查 [] 但在这种情况下,恕我直言并不重要

【问题讨论】:

  • (/+/) 的类型签名是(/+/) :: a -> Stack [a] -> Stack [a],因此对于您的实例Stacked Stack a,这意味着(/+/) 的类型为Stack a -> Stack [Stack a] -> Stack [Stack a]。你可能想用(/+/) :: a -> s a -> s a 来创建一个class Stacked s 类。

标签: class haskell instance newtype


【解决方案1】:

如果您查看Foldable 是如何定义和实例化的,您可能希望将其编码为

class Stacked a  where 
    (/+/) :: x -> a x -> a x
    pop :: a x -> a x

instance Stacked Stack where
    (/+/) x (Stack xs) = Stack (x:xs) 
    pop (Stack []) = Stack []
    pop (Stack xs) = Stack (tail xs)

这样Stacked 类型类可以为任何类型实现,而不依赖于类型Stack

也通过将Stack定义为

newtype Stack a = Stack [a] deriving (Show)

我们可以简单地通过写Stack Int而不是Stack [Int]来使用它,这样Stack的实现(它在内部使用一个列表)对用户隐藏。

对一元函数使用运算符不太好,我会使用普通函数。

而且您肯定应该捕获空列表的情况,并且可能应该将isEmpty 之类的函数添加到类型类中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-15
    • 1970-01-01
    相关资源
    最近更新 更多