gpt4 book ai didi

haskell - 完成同样的任务有哪些替代方案?

转载 作者:行者123 更新时间:2023-12-02 14:56:08 25 4
gpt4 key购买 nike

我有一个在父函数中实例化的结构,我想通过调用该父函数中的函数来修改该实例化数据。这是一个人为的示例:

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 而不对其进行任何操作。那, parent 可能还必须处理 MyList 和另一个返回值(例如,-> (Bool, MyList))。

因此,您可以想象一个函数调用的树结构,所有函数调用都需要 MyList 参数和返回值;这似乎不是最佳选择。

这里有一个更具体的例子来说明我正在谈论的事情。浏览代码 https://github.com/mokehehe/monao (haskell 中的 super 马里奥克隆)。您将看到 state.monad 从未被使用,并且有必须在整个代码中流动的上层结构(例如,Main.hs 中的 GameGame)。

最佳答案

您可以使用 RecordWildCards 使其更加简洁。扩展名:

{-# LANGUAGE RecordWildCards #-}
import Data.List (insert)

addIntToList :: Int -> MyLists -> MyLists
addIntToList x ml@MyLists{..} = ml{ myInts = insert x myInts }

MyLists{..} 模式将 MyLists 记录的属性转储到作用域中。因此,我们可以在初始化新的 myInts 时轻松引用旧的 myInts

相反,如果您在表达式上下文中使用..,它将用范围内的相应名称填充未初始化的属性。 addIntToList 函数也可以写成:

addIntToList x MyLists{..} = MyLists{ myInts = insert x myInts, .. }

使用记录通配符还可以做一件很酷的事情:

someAction = do
myInts <- getInts :: IO [Int]
myBools <- getBools :: IO [Bool]
return MyLists{..}

此外,Data.List.insert 有点冗长。您可以只说插入,因为此导入:

import Data.List

会将 Data.List 中的所有名称导入到命名空间中。如果您不喜欢这样(例如,因为您想在自己的模块中定义一个名为 insert 的函数),您可以导入它:

import qualified Data.List as List

… List.insert …

就在程序中使用 MyLists 而言,StateT monad 转换器非常有用:

{-# LANGUAGE RecordWildCards #-}
import Control.Monad.State

...

printList :: StateT MyLists IO ()
printList = liftIO . print =<< get

program :: StateT MyLists IO ()
program = do
printList
modify $ addIntToList 4
printList
modify $ addBoolToList True
printList

main :: IO()
main = evalStateT program $ MyLists [1,2,3] [False, True, False]

关于haskell - 完成同样的任务有哪些替代方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10606180/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com