Haskell:泛型和INT的泛型类型

时间:2016-12-02 14:16:18

标签: haskell generics types module

我正在为大学项目开发​​一个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]之类的东西?任何帮助都将得到帮助。

2 个答案:

答案 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