我正在为大学项目开发一个Stack模块。 它被认为是一个通用"令牌列表"因此我使用了这个构造函数:
module Stack (Stack(S), dup, swap, pop, size) where
import Prelude
data Stack a = S [a]
但是在大小操作上,我可以将列表的大小添加到其头部,如下所示:
size[1,2,3,4] = [4,1,2,3,4]
但我似乎无法定义此函数,因为在签名中它接收一个通用列表并返回一个通用列表,但实际上它返回一个带有INT的通用列表
size :: Stack a -> Stack a
size (S xs) = S(sizeAux xs)
sizeAux :: [a] -> [a]
sizeAux [] = [0]
sizeAux xs = length xs:xs
我尝试使用Show like
sizeAux :: [a] -> [a]
sizeAux [] = ["0"]
sizeAux xs = show((length xs)):xs
但我得到了同样的错误,只有这次是[Char]
有没有办法绕过这个而不将Stack构造函数改为[String]之类的东西?任何帮助都将得到帮助。
答案 0 :(得分:3)
如果您尝试以FORTH的方式构建堆栈计算机(例如,正如您的size
建议的那样),则使用[a]
进行堆栈的可能性不大特技。
一种简单直接的方法是首先确定机器将要处理的原始数据类型,然后为每种单独的类型创建一个带有构造函数的数据类型,例如:
data Data = I Int | S String | Error String
deriving Show -- for convenience only
然后,堆栈计算机的状态将是[Data]
类型 - 在这种情况下,它将允许您对int和字符串进行计算,以及处理“带外”错误。
然后您的size
运算符将如下所示:
size :: [Data] -> [Data]
size xs = I (length xs) : xs
答案 1 :(得分:1)
如果你真的想要这个,你可以这样做:
import Data.List
size :: Num a => Stack a -> Stack a
size (S xs) = S (sizeAux xs)
sizeAux :: Num a => [a] -> [a]
sizeAux xs = genericLength xs : xs