我有一个在父函数中实例化的结构,我想通过从该父函数调用函数来修改该实例化数据。这是一个人为的例子:
import Data.List
data MyLists = MyLists {
myInts :: [Int],
myBools :: [Bool]
} deriving (Show)
addIntToList :: Int -> MyLists -> MyLists
addIntToList x main_lists =
main_lists { myInts = Data.List.insert x my_ints }
-- might make a call to another child function that modifies main_list here, and so on (i.e., this is the vertical problem I see with this structuring)
where
my_ints = myInts main_lists
main :: IO()
main = do
let my_main_lists = MyLists [1,2,3] [False, True, False]
let my_new_main_lists = addIntToList 4 my_main_lists
print my_new_main_lists
let my_new_new_main_lists = addBoolToList True my_new_main_lists
print my_new_new_main_lists
-- and so on (this is the lateral problem I see with this code structuring)
构建此代码或完成类似任务的替代方法是什么?有没有更简洁的方法?
我应该补充一点,一旦您对子函数进行一长串函数调用,这会变得特别臭(即代码气味);他们最终都需要返回一个新的MyLists
或者只是返回main_list
而不做任何事情。那,父母可能还必须处理MyList
另一个返回值(例如,-> (Bool, MyList)
)。
所以,你可以想象一个函数调用的树结构都需要一个 MyList 参数和返回值;这似乎不是最优的。
这是我正在谈论的那种事情的更具体的例子。在https://github.com/mokehehe/monao浏览代码(haskell 中的超级马里奥克隆)。您会看到 state.monad 从未被使用过,并且存在必须贯穿整个代码的上层结构(例如 Main.hs 中的 GameGame)。