自定义类型类的类型麻烦

马可

我在学习Haskell时遇到类型问题。我有一个类型类称为Stack,显然应该表现得像一个堆栈。我有一个Elem简单地是Int或Bool的类型。

现在,我希望我的函数采用StackofElem并对其进行一些操作。结果实际上并不重要,但是我什至无法获取堆栈的第一个元素,而且现在也无法在数小时内找出问题所在。

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

我得到的错误是

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)

我真的不明白为什么Haskell拒绝此操作(甚至拒绝简单地调用top st我的函数而无需我尝试指定类型)。

我希望有人能对此有所启发!

克罗基亚

正如两个评论者所建议的,您需要-XScopedTypeVariables

以下代码为我编译:

{-# 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

我不确定您对“无法使用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

您仍然需要ScopedTypeVariables

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

UWP拖放自定义类型/类

来自分类Dev

在Nat类上定义自定义类型族

来自分类Dev

Python:使用自定义数字类或类型

来自分类Dev

在Java中返回自定义数据类型(类?)

来自分类Dev

实例成员不能用于自定义类的类型

来自分类Dev

JAXB生成实现自定义接口的某些类型的类

来自分类Dev

使我的自定义列表类返回“列表”作为类型

来自分类Dev

列出自定义类成员和类型

来自分类Dev

Swift-创建类型为Array的自定义类

来自分类Dev

具有自定义类类型的键的哈希图

来自分类Dev

C#/类和自定义类型

来自分类Dev

带有 POJO 类的 GreenDao 中的自定义类型

来自分类Dev

如何与自定义类的类型进行比较

来自分类Dev

如何为自定义类的参数指定类型提示?

来自分类Dev

对自定义类类型中的控件列表进行排序

来自分类Dev

如何检查类型是否为自定义类

来自分类Dev

自定义类型转换

来自分类Dev

如何构建自定义阅读器monad以及自定义类型类?

来自分类Dev

嵌入自定义类时猜测自定义表单类型

来自分类Dev

Oracle自定义类向导无法从Oracle用户定义的数据类型生成自定义c#类

来自分类Dev

为自定义类提供标准类型,但可以添加其他类型

来自分类Dev

如何添加自定义类型定义?

来自分类Dev

如何添加自定义类型定义?

来自分类Dev

定义自定义数据类型

来自分类Dev

反应自定义类型定义

来自分类Dev

自定义android视图的“自定义类型”属性

来自分类Dev

自定义类错误:类型不完整且无法定义

来自分类Dev

自定义属性类型的Model Binder

来自分类Dev

展开自定义列表类型