0

我对 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”)。

4

1 回答 1

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

注意,我还更改了 的定义,moduleMethod这样 egprocessFunction就不必为ThisModulesInternal.

于 2012-07-30T19:44:46.717 回答