我仍然不完全熟悉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"例如)发生在模块的用户实现中。
答案 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}}。