如何让我的模块实现用户定义的数据类(当前使用字符串)

时间:2012-07-30 18:55:55

标签: haskell

我仍然不完全熟悉Haskell,但当我自己做一些练习时,我遇到了一个似乎未来会出现的问题。即使它没有,我想知道将来如何做到这一点。

假设我有一个模块

module UserType where

data ThisModulesData = UserData String | ThisModulesInternal Int

moduleMethod :: (ThisModulesData -> Int) -> ThisModulesData -> Int
moduleMethod func dat = case dat of
    UserData _             -> func dat
    ThisModulesInternal i -> i

processList :: (ThisModulesData -> Int) -> [ThisModulesData] -> Int
processList func xs = sum $ map (moduleMethod func) xs

然后,如果我想使用这个模块,我会有像

这样的东西
dataList :: [ThisModulesData]
dataList = [UserData "Type1", UserData "Type2", ThisModulesInternal 8]

processFunction :: ThisModulesData -> Int
processFunction (UserData command) = case command of
    "Type1" -> 1
    "Type2" -> 2
    _       -> 0
processFunction _ = 0

result :: Int
result = processList processFunction dataList

我想要做的是用更像haskell的字符串替换字符串,这样它是类型安全的,并且如果我有

可能引发编译错误
dataList = [UserData "Wrong", UserData "ThisIsWrong", ThisModulesInternal 97]

感谢。感谢StackOverflow的帮助,我在学习Haskell方面度过了非常愉快的时光。

编辑:

要澄清,我希望我的模块文件保持静态,并且需要更改的内容(如果我想添加" type3"例如)发生在模块的用户实现中。

1 个答案:

答案 0 :(得分:1)

使用类型参数。

module UserType where

data ThisModulesData a = UserData a | ThisModulesInternal Int

moduleMethod :: (a -> Int) -> ThisModulesData a -> Int
moduleMethod func dat = case dat of
    UserData x            -> func x
    ThisModulesInternal i -> i

processList :: (a -> Int) -> [ThisModulesData a] -> Int
processList func xs = sum $ map (moduleMethod func) xs

然后

data Ours = Type1 | Type2
type OurData = ThisModulesData Ours

dataList :: [OurData]
dataList = [UserData Type1, UserData Type2, ThisModulesInternal 8]

processFunction :: Ours -> Int
processFunction command = case command of
    Type1 -> 1
    Type2 -> 2

result :: Int
result = processList processFunction dataList

n.b。我还修改了moduleMethod的定义,以便例如processFunction ThisModulesInternal无需担心{{1}}。